Shell script 中的 array 一直是一个比较模糊的概念,在网上找到的相关文章也讲得不太详细。本文参考了多篇文章,以尽量详尽地讲解一下 bash 中的 array。
Array 基础语法
Array 初始化
Array 有多种方式进行初始化:
- 使用
array_name[xx]
- 使用显式声明语句
declare -a array_name
array_name=( XXX YYY ZZZ ... )
(括号旁边的空格不是必需的)array_name=([xx]=XXX [yy]=YYY ...)
下面我们通过代码演示一下:
1 |
|
下面举一个实际应用中初始化 array 的例子:
1 | base64_charset=( {A..Z} {a..z} {0..9} + / = ) |
可以看到,用 array=( element1 element2 ... elementN )
这种方式初始化 array 非常方便
输出整个 array
echo ${array_name[@]}
1 | base64_charset=({A..Z} {a..z} {0..9} + / =) |
取 array 中元素的值
在中括号中加数字或字符串索引可以取到 array 中某一元素的值:${array_name[xx]}
正常情况下,不要放置字符串索引,除非你精通 array
- 当索引为数字时,会返回相应的值(在那个索引的值被指定的情况下)
- 当索引为字符串且不是变量名时,无论那个字符串是什么,都会返回 array 中最后一个字符串索引对应元素的值
- 当索引为变量名时,其会被展开(不需要加
$
符号)
1 | array_0=([far]=faraway [he]=hello [24]=kube [no]=love [17]=docker) |
Array 中的元素索引
- 整数索引从 0 开始
- 元素的整数索引不必是连续的,即元素之间可以有 gap
取 array 长度
${#array_name}
array 中第一个元素的长度${#array_name[*]}
array 的长度${#array_name[@]}
array 的长度
1 | array=( zero one two three four five ) |
取 array 中某一元素的长度
${#array_name[n]}
1 | array=( zero one two three four five ) |
对 array 进行切片
Array 对切片和 python 中的切片很像:
${array_name[@]:start}
从 start 开始的所有元素(包含 start )${array_name[@]:start:end}
从 start 到 end 的所有元素(包含 start,不包含 end )
1 | arrayZ=( one two three four five five ) |
一切皆是 array
需要注意的是,即使我们并没有按照前面提到的几种方法将一个变量声明为 array, 我们仍然可以对其进行 array 相关的操作。
换句话来说:所有变量都可以被看作 array 。
比如说,下面这个例子中的变量 string
其实也是一个 array(包含一个元素):
1 | string=abcABC123ABCabc |
Array 进阶语法
对 array 中的第一个元素切片
$(array_name:start)
返回 array_name[0][start:] (包含 start )$(array_name:start:end)
返回 array_name[0][start:end] (包含 start ,包含 end )
示例:1
2
3
4
5
6
7
8
9
10
11
12
13array=( zero one two three four five )
# Element 0 1 2 3 4 5
echo ${array[0]} # zero
echo ${array:0} # zero
# Parameter expansion of first element,
#+ starting at position # 0 (1st character).
echo ${array:1} # ero
# Parameter expansion of first element,
#+ starting at position # 1 (2nd character).
echo ${array:1:2} # er
# Parameter expansion of first element,
#+ starting at position # 1 (2nd character).
切除子字符串
${array_name[scope][flag][pattern]}
scope:
@
|*
表示对全部元素进行操作- n 表示对只第 n 个元素进行操作
flag:
#
最短匹配,从头部开始##
最长匹配,从头部开始%
最短匹配,从尾部开始%%
最长匹配,从尾部开始
pattern: 通配符,可以使用 * 匹配任意长度字符串
${array_name[@]#pattern}
移除 pattern 的最短匹配(从字符串头部开始匹配)${array_name[@]##pattern}
移除 pattern 的最长匹配(从字符串头部开始匹配)${array_name[@]*pattern}
移除 pattern 的最短匹配(从字符串尾部开始匹配)${array_name[@]**pattern}
移除 pattern 的最长匹配(从字符串尾部开始匹配)
1 | # Substring Removal |
Array 演进史
在 bash-2.0 中,bash 增加了对于用整数作为数组索引的支持,且索引部分可以使用算术表达式:
The shell now supports integer-indexed arrays of unlimited length, with a new compound assignment syntax and changes to the appropriate builtin commands (declare/typeset, read, readonly, etc.). The array index may be an arithmetic expression.
未完待续