Shell 不提供数组,Bash 提供了一维索引数组和一维的关联数组。索引数组通过整数下标进行访问,而关联数组通过字符串下标进行访问。
索引数组
声明
通过如下方式声明一个索引数组
declare -a arr
虽然索引数组可以不用先声明,但是为了与关联数组的使用方式保持一致,我习惯对索引数组进行声明。
赋值
可以通过如下方式给数组赋值
declare -a arr
arr=( hello world )
声明和赋值两个操作可以一起使用,如下
declare -a arr=( hello world )
注意,数组变量、等于号、开括号之间不能有空白字符(空格、TAB、换行符)。括号内的数组项是通过空白字符进行分割的,因此下面形式的赋值也是有效的。
declare -a arr=(
hello
world
)
我们还可以给索引数组赋值的时候指定索引号,索引号可以是不连续的
declare -a arr=( [0]=hello [2]=world )
数组下标为1的项没有赋值,默认为空。
以上都是给整个数组赋值,我们也可以对单个数组项进行赋值,例如
declare -a arr=( [0]=hello [2]=world )
arr[1]=china
关联数组
声明
关联数组可以通过如下方式声明
declare -A arr
注意,关联数组必须要声明,后使用。
赋值
关联数组的赋值如下
declare -A arr=( [name]=value [hello]=world )
当然,也可以单独给关联数组的元素赋值
declare -A arr=( [name]=value [hello]=world )
arr[country]=china
数组访问
通过 ${name[subscript]}
可以访问数组元素,例如
declare -a arr1=( hello world )
declare -A arr2=( [key1]=hello [key2]=world )
echo ${arr1[0]}
echo ${arr2[key1]}
对于索引数组,如果索引值为负值,例如 -1 表示最后一个元素,-2 表示倒数第二个元素。
如果 ${name[subscript]}
中的 subscript
是 @
或*
,那么会展开为所有数组元素的值。
#!/bin/bash
declare -a arr=( hello world )
for i in ${arr[@]};do
echo $i
done
echo "==============="
for i in ${arr[*]}; do
echo $i
done
这个脚本的执行结果为
hello
world
===============
hello
world
从执行结果可以看出,${arr[@]}
和${arr[*]}
没有区别。但是如果把这个整体加上双引号,那就有区别了
#!/bin/bash
declare -a arr=( hello world )
for i in "${arr[@]}";do
echo $i
done
echo "==============="
for i in "${arr[*]}"; do
echo $i
done
执行结果为
hello
world
===============
hello world
从结果中可以看出
"${arr[@]}"
展开为两个值,这个两个值分别为数组的两个元素的值。
"${arr[*]}"
只展开为一个值,这个值包含了所有数组元素的值。
在实际中,通常都是优先使用@
数组长度
#!/bin/bash
declare -a arr=( hello world )
echo "arr length is ${#arr[@]}"
${#arr[@]}
会展开为数组元素的长度,它是 shell 参数展开的一种形式。
但是,${#arr[0]}
会展开为数组中第一个元素的长度。
数组索引集合
${!name[@]}
和 ${!name[*]}
会展开为所有元素的索引,如果加上双引号,效果与上面讲的一样。
#!/bin/bash
declare -a arr=( [1]=hello [3]=world )
for i in "${!arr[@]}"; do
echo $i
done
echo "==============="
for i in "${!arr[*]}"; do
echo $i
done
执行结果为
1
3
===============
1 3
向数组后添加元素
#!/bin/bash
declare -a arr1=( [1]=hello [3]=world )
declare -A arr2=( [key1]=value1 [key2]=value2 )
arr1+=( china )
echo ${arr1[@]}
arr2+=( [key3]=value3 )
echo ${arr2[@]}
执行结果为
hello world china
value3 value2 value1