Shell数组:shell数组的定义、数组长度
Shell在编程方面比Windows批处理强大很多,无论是在循环、运算。
bash支持一维数组(不支持多维数组),并且没有限定数组的大小。类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。
定义数组
在Shell中,用括号来表示数组,数组阿元素用“空格”符号分割开。定义数组的一般形式为:
array_name=(value1 ... valuen)
例如:
array_name=(value0 value1 value2 value3)
#数组也是一个变量,只不过他有多个值,区别在于定义了数组,有多种取值方式
[root@hass-12 ~]# a=`ls /tmp`;echo $a
check.sh systemd-private-14b199c09fb346a0a1464e9334e57ec3-nginx.service-gU1I5K systemd-private-45002b0a75ba46079a70971b526f8584-nginx.service-dI2xZr systemd-private-bbac906744e645909ee6c515c1540d4e-nginx.service-rokXRe vmware-root_6813-3879179888 vmware-root_6816-2822835213 vmware-root_6822-2822966282
或者
array_name=(
value0
value1
value2
value3
)
array_name=(
["0"]=value0
["1"]=value1
["2"]=value2
["3"]=value3
)
还可以单独定义数组的各个分量:
#可以不使用连续的下标,而且下标的范围没有限制。
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
array_name[5]=value5
array_name=([0]=0 [1]=1 [5]=5)
array_name=([5]=5 [0]=0 [1]=1) #不按顺序
array_name=(`ls .`)
array_name[-1]=value5 #定义数组最后一个元素
array_name[-2]=value5
使用数组
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
纯文本复制
# 取得数组元素的个数
length=${#array_name[@]}
# 或者
length=${#array_name[*]}
# 取得数组单个元素的长度
lengthn=${#array_name[n]}
${#res[]} #取变量的字符个数,或元组内元素的个数,或元组内某个元素的字符个数
读取数组
读取数组元素值的一般格式是:
${array_name[index]}
例如:
valuen=${array_name}
valuen=${array_name[2]}
#不指定索引或下标,取第一个值
使用@ 或 * 可以获取数组中的所有元素,例如:
${array_name[*]}
${array_name[@]}
查看系统中有哪些数组
declare可以声明变量的种类和属性,declare扩展
#查看所有数组
[root@hass-11 ~]# name=(1 2 3)
[root@hass-11 ~]# declare
#查看所有普通数组
[root@hass-12 ~]# declare -a |grep name
name=([0]="1" [1]="2" [2]="3")
#查看所有关联数组
[root@hass-11 ~]# declare -A |grep name
declare -A array='([gender]="male" [name]="syy" [age]="18" )'
查看数组的索引
[root@hass-11 ~]# a=(a b c)
[root@hass-11 ~]# echo ${a[1]}
b
[root@hass-12 ~]# echo ${a[*]}
1 2 3
[root@hass-11 ~]# echo ${!a[a]} #索引取值,不能是值取索引
-bash: a: expression recursion level exceeded (error token is "a")
[root@hass-11 ~]# echo ${!a[*]}
0 1 2
删除
#删除元组
unset array
#指定索引删除
[root@hass-11 ~]# a=1
[root@hass-11 ~]# a=(1 2 3 4 "aaa") #变量被数组覆盖
[root@hass-11 ~]# echo $a
1
[root@hass-11 ~]# echo ${a[@]}
1 2 3 4 aaa
[root@hass-11 ~]# unset a #删除数组
[root@hass-11 ~]# echo $a
[root@hass-11 ~]# a=(1 2 3 4 "aaa")
[root@hass-11 ~]# unset a[0] #删除数组里的元素
[root@hass-11 ~]# echo ${a[*]}
2 3 4 aaa
#指定元素删除,不改变原数组
[root@hass-11 ~]# echo ${a[*]}
one two tree fore five six
[root@hass-11 ~]# unset ${a[two]}
[root@hass-11 ~]# echo ${a[*]}
one two tree fore five six
[root@hass-11 ~]# unset ${a[*]#two}
[root@hass-11 ~]# echo ${a[*]}
one two tree fore five six
截取
#指定元素截取(顾左不顾右)
[root@hass-11 ~]# echo ${a[*]:two}
one two tree fore five six
[root@hass-11 ~]# echo ${a[*]:two:1}
one
[root@hass-11 ~]# echo ${a[*]:two:2}
one two
[root@hass-11 ~]# echo ${a[*]::two:2} #数组不支持从右边截取
-bash: a[*]: two:2: syntax error in expression (error token is ":2")
替换,删除
#指定元素替换
[root@hass-11 ~]# echo ${a[*]}
one two tree fore five six
[root@hass-11 ~]# echo ${a[*]/one/two}
two two tree fore five six
[root@hass-11 ~]# echo ${a[*]//two/one} #匹配多个
one one tree fore five six
[root@hass-11 ~]# echo ${a[*]//one/} #删除元组内的元素,但不是真正的删除
two tree fore five six
[root@hass-11 ~]# echo ${a[*]}
one two tree fore five six
关联数组
关联数组指的是可以指定 (["key"]:"value")
#定义一个普通数组,declare -a 可以省略
[root@hass-11 ~]# declare -a array=("a" "b" "c" "d")
[root@hass-11 ~]# echo ${array[*]}
a b c d
#定义一个关联数组
[root@hass-11 ~]# declare -A array=(["name"]="syy" ["age"]=18 ["gender"]="male")
#取关联数组的value
[root@hass-11 ~]# echo ${array["name"]}
syy
#取关联数组的key
[root@hass-11 ~]# echo ${!array["syy"]} #只能通过key取value,不能通过value取key
...
#查看关联数组所有value,数组内元素是没有顺序的
[root@hass-11 ~]# echo ${array[*]}
male syy 18
#查看关联数组所有key
[root@hass-11 ~]# echo ${!array[*]}
gender name age
#同种属性的值使用普通数组
#不同属性使用关联数组
#数据可以自由选择不同的数组
数组的遍历
遍历普通数组的方式1,取值
array=(one two three four five fire)
for i in ${array[*]}
do
echo $i
done
遍历普通数组的方式2,取索引,再取值
array=(one two three four five fire)
for i in ${!array[*]}
do
echo $i ${array[$i]} # 获取索引及其对应的元素
done
遍历关联数组的方式1,取value
declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")
for x in ${array[*]}
do
echo $x
done
遍历关联数组的方式2,取key,进而取value
declare -A array=(["name"]="egon" ["age"]=18 ["gender"]="male")
for k in ${!array[*]}
do
echo $k ${array[$k]}
done
练习:数组的使用
基于关联数组统计/etc/passwd文件中不同种类shell的个数
[root@egon day06]# cat 11.sh
#!/bin/bash
declare -A shell_count
while read line
do
shell=`echo $line|awk -F: '{print $7}'`
let shell_count["$shell"]++
done < /etc/passwd
for key in ${!shell_count[*]}
do
echo $key : ${shell_count["$key"]}
done
[root@egon day06]# ./11.sh
/sbin/nologin : 22
/bin/sync : 1
/bin/bash : 4
/sbin/shutdown : 1
/sbin/halt : 1
#普通数组的自增
。。。无意义
#关联数组的自增
[root@hass-12 ~]# declare -A d_name
[root@hass-12 ~]# let d_name["age"]++ #1.定义一个key 2.value从0开始自增
[root@hass-12 ~]# echo ${d_name[*]}
1
[root@hass-12 ~]# echo ${!d_name[*]}
age
[root@hass-12 ~]# echo ${d_name["age"]}
1
[root@hass-12 ~]# let d_name["age"]++
[root@hass-12 ~]# let d_name["age"]++
[root@hass-12 ~]# let d_name["age"]++
[root@hass-12 ~]# echo ${d_name[*]}
4
[root@hass-12 ~]# echo ${!d_name[*]}
age