Shell 不提供數組,Bash 提供了一維索引數組和一維的關聯數組。索引數組通過整數下标進行通路,而關聯數組通過字元串下标進行通路。
索引數組
聲明
通過如下方式聲明一個索引數組
declare -a arr
雖然索引數組可以不用先聲明,但是為了與關聯數組的使用方式保持一緻,我習慣對索引數組進行聲明。
指派
可以通過如下方式給數組指派
declare -a arr
arr=( hello world )
聲明和指派兩個操作可以一起使用,如下
注意,數組變量、等于号、開括号之間不能有空白字元(空格、TAB、換行符)。括号内的數組項是通過空白字元進行分割的,是以下面形式的指派也是有效的。
declare -a arr=(
hello
world
)
我們還可以給索引數組指派的時候指定索引号,索引号可以是不連續的
數組下标為1的項沒有指派,預設為空。
以上都是給整個數組指派,我們也可以對單個數組項進行指派,例如
declare -a arr=( [0]=hello [2]=world )
arr[1]=china
關聯數組
聲明
關聯數組可以通過如下方式聲明
declare -A arr
注意,關聯數組必須要聲明,後使用。
指派
關聯數組的指派如下
當然,也可以單獨給關聯數組的元素指派
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