天天看点

linux shell编程学习——数组使用定义赋值与引用获取全部key获取长度获取全部下标key括号操作()遍历数据删除元素切片操作替换操作

linux的shell的编程方面很强大,最近在写脚本的时候,需要用到shell的数组。下面对最近的学习和使用做个简单的总结。

定义

linux的数组分两种,一种是普通的下标数组,一种是关联数组。前者和其他语言的数据一样通过下标进行访问。关联数组,可以通过key来获取值,key可以是数字或字符串。两者比较像高级语言Java里面的array和map。

关联数组

关联数据可以使用declare -A 声明。

[email protected]:tmp$ cat array.sh 
declare -A arr;
arr["a"]=b;
echo ${arr["a"]};
[email protected]:tmp$ ./array.sh 
b
           

普通数组

普通数组,可以通过declare -a声明。

[email protected]:tmp$ cat ./array2.sh 
declare -a arr;
arr[]=b;
echo ${arr[0]};
[email protected]:tmp$ ./array2.sh 
b
           

赋值与引用

定义完数组之后,当然就是使用了,shell里数组都是通过下标进行赋值和引用。赋值语法:数组名[下标]=字符串 。在赋值的时候,等号左右是不能有空格的,shell是空格敏感的, 下标和字符串,引号不是必须的

引用数组元素,则使用${数组名[下标]}

关联数组

关联数组的下标,可以使字符串,也可以是数字。如果下标存在,则会覆盖之前的值,如果下标不存在,则会添加新的下标。在引用的时候,如果下标不存在,不会报任何错误,只会返回空字符串。

[email protected]:tmp$ cat ./map_arr.sh 
declare -A arr;
echo ${arr[ab]}
arr[ab]="letter_a"
echo ${arr[ab]}
arr[ab]="letter_b"
echo ${arr[ab]}
[email protected]:tmp$ ./map_arr.sh 

letter_a
letter_b
           

普通数组

普通数组的赋值和引用,也是通过下标进行的,但普通数组只能使用数组作为下标,如果使用非数字,则默认为0。普通数组,不一定需要从0开始赋值。

[email protected]:tmp$ cat index_arr.sh 
declare -a arr;
echo ${arr[0]}
arr[]="one"
echo ${arr[1]}
arr[aa]="zero"
echo ${arr[0]}
[email protected]:tmp$ ./index_arr.sh 

one
zero
           

获取全部key

可以一次性输出数组的所有值;通过: 数组名[∗]或 {数组名[@]}

[email protected]:tmp$ cat index_arr.sh 
declare -a arr;
echo "all element:"${arr[*]}
arr[]="one"
echo "all element:"${arr[*]}
arr[aa]="zero"
echo "all element:"${arr[*]}
arr[]="one_1"
echo "all element:"${arr[@]}
[email protected]:tmp$ ./index_arr.sh 
all element:
all element:one
all element:zero one
all element:zero one_1
           

获取长度

获取数组长度,和获取数组全部值相比,多个#号。

通过:${#数组名[*]} 或 ${#数组名[@]} 可以得到数组的长度。

shell中,也可以获取数组元素的长度;通过:echo ${#数组名[下标]}

[email protected]:tmp$ cat index_arr.sh 
declare -a arr;
echo ${#arr[*]}
arr[]="one"
echo ${#arr[*]}
arr[aa]="zero"
echo ${#arr[*]}
arr[]="one_1"
echo ${#arr[@]}

declare -A arr2;
echo ${#arr2[@]}
arr2["a"]="aa"
echo "arr2 length:${#arr2[@]}"
echo "arr2[a] length:${#arr2[a]}"
[email protected]:tmp$ ./index_arr.sh 





arr2 length:
arr2[a] length:
           

获取全部下标key

获取数组全部key,语法:

!数组名[∗]或 {!数组名[@]}

[email protected]:tmp$ cat index_arr.sh 
declare -a arr;
echo ${!arr[*]}
arr[]="one"
echo ${!arr[*]}
arr[aa]="zero"
echo ${!arr[*]}

declare -A arr2;
arr2[aa]="value"
echo ${!arr2[*]}
[email protected]:tmp$ ./index_arr.sh 


 
aa
           

从上面的代码,可以看出,如果对普通数据使用非数字下标,则相对于对于下标0进行操作。

括号操作()

在linux bash中,有个特殊的变量,叫IFS(Internal Field Separator),当shell需要对字符串进行分割时,则使用IFS值作为分割符。该字段的默认值为空格,回车和tab符。shell中将字符串放在括号内,则会将字符串分割成数组。

[email protected]:tmp$ cat index_arr.sh 
arr=(aa bb cc)
echo "key:"${!arr[*]}
echo "val:"${arr[*]}
[email protected]:tmp$ ./index_arr.sh 
key:  
val:aa bb cc
           

IFS的值,也是可以改变,因为IFS是个全局变量。改变IFS值后,在使用结束后,最好将IFS值改回默认值,这样避免其他使用IFS默认值的脚本不会产生bug。下面是一种改变IFS值的方法。

OLD_IFS=$IFS
IFS=","
IFS=$OLD_IFS
           

遍历数据

  1. 普通数组遍历,得到长度,然后使用下标进行变量
[email protected]:tmp$ cat list_array.sh 
declare -a arr=(a b c);
for (( i=; i<${#arr[@]}; ++i));do
    echo ${arr[$i]};
done
[email protected]:tmp$ ./list_array.sh 
a
b
c
           
  1. 使用for in方式进行变量
[email protected]:tmp$ cat list_array.sh 
declare -a arr=(a b c);
for val in ${arr[*]};do
    echo ${val}
done

declare -A arr2;
arr2["a"]=aa
arr2["b"]=bb
arr2["c"]=cc
for val in ${arr2[@]};do
    echo ${val};
done
[email protected]:tmp$ ./list_array.sh 
a
b
c
aa
bb
cc
           

删除元素

使用unset关键字可以删除整个数组,或者数组内的某个元素。

[email protected]:tmp$ cat unset_array.sh 
arr=(a b c)
echo ${!arr[*]},${arr[*]}
unset arr[]
echo ${!arr[*]},${arr[*]}
unset arr
echo ${!arr[*]},${arr[*]}

echo "-------------"

declare -A arr2;
arr2["a"]=aa
arr2["b"]=bb
arr2["c"]=cc
echo ${!arr2[*]},${arr2[*]}
unset arr2[a]
echo ${!arr2[*]},${arr2[*]}
unset arr2
echo ${!arr2[*]},${arr2[*]}

[email protected]:tmp$ ./unset_array.sh 
  ,a b c
 ,a c
,
-------------
a b c,aa bb cc
b c,bb cc
,
           

切片操作

shell中的数组,支持切片操作。通过:${数组名[@或*]:起始位置:长度} 可以进行数组的切片操作;

切片操作返回一个以空格分隔的字符串,原数组数据不变。如果想把结果转成数组,则可以使用上面介绍的括号操作。

[email protected]:tmp$ cat index_arr_slice.sh 
arr=(    )
echo ${arr[@]:0:3}
echo ${arr[@]:6:3}
echo ${arr[@]:1:7}
echo ${arr[@]:-1:7}
echo ${arr[@]:-1:2}

echo "------"

declare -a arr2;
arr2[]=
arr2[]=
echo ${arr2[@]:0:1}
echo ${arr2[@]:1:2}
echo ${arr2[@]:2:2}
echo ${arr2[@]:3:2}

echo "-------"
new_arr=(${arr[@]:0:3})
echo ${new_arr[*]}
[email protected]:tmp$ ./index_arr_slice.sh 
  

   
    
    
------

 


-------
  
           

从上面的测试程序输出结果,可以看出,shell的数组下标,不一定需要从0开始,但在进行切片的时候,shell数组会自动跳过那些不存在的下标。

替换操作

shell数组,支持替换操作,可以通过:${数组名[@]/待替换字符串/替换字符串} 进行数组替换操作。

将数组的所有值都输出,相当于一个字符串,对于数组的替换,其实和shell字符串的替换操作是一样的,具体可以参考

[ linux shell编程学习–字符串的使用和操作 ](

http://blog.csdn.net/shuanghujushi/article/details/51298672 )

[email protected]:tmp$ cat replace_arr.sh 
declare -A arr2;
arr2["a"]=aa
arr2["b"]=bb
arr2["c"]=cc

echo ${arr2[@] /a/d}
echo ${arr2[@] //b/e}
[email protected]:tmp$ ./replace_arr.sh 
da bb cc
aa ee cc