shell 数组变量
普通数组:只能使用整数作为数组索引
关联数组:可以使用字符串作为数组索引
数组变量和普通变量的区别:最明显的曲边就是普通变量一次只能设置一个变量值,而数组可以有多个值,例如普通变量(ip=192.168.81.210),数组变量(ip=(192.168.81.210 192.168.81.220)),普通变量是按一个字符当做一个索引位,而数组变量是一个字符串作为一个变量,另外普通变量的索引位都是整数,从0开始,而数组变量可以是整数也可以是字符串,这就要说到关联数组,例如(info=([name]tianyun [sex]male))
1.普通数组
定义数组:
方法一:一次性赋一个值
格式:数组名[下标/索引]=变量值
例子:array1[0]=pear
array1[1]=apple
array1[2]=orange
array1[3]=peach
默认只输出第一个索引
查看数组
1:declare -a | grep 数组名
2:echo a r r a y [ @ ] 查 看 数 组 中 的 所 有 值 , e c h o {array[@]}查看数组中的所有值,echoarray[@]查看数组中的所有值,echo{array[1]}以索引位进行显示
方法二:一次赋多个值
格式:数组名=(变量值1 变量值2)
例子:array2=(tom jack alice)
array3=($(cat /etc/passwd)) 希望以文件中的每行作为一个元数赋值给数组array3,但是文件中可能存在空格或者空行,因此可以使用IFS重新定义分隔符
[root@localhost ~]# array4=($(ls /var/ftp/Shell/for*)) [root@localhost ~]# array5=(tom jack alice "bash shell") [root@localhost ~]# colors=($red $blue $gree $recolor) [root@localhost ~]# array6=(1 2 3 4 5 6 7 "linux shell" [20]=saltstack)
2.关联数组
关联数组与普通数组不同之处在于,关联数组的索引不再是默认的整数,而是由管理员自己定义
格式:数组名=([][][索引1]=元数值 [索引2]=元数值)
像存在的数组中增加索引:数组名+=([索引3]=元数值)
例如:userinfo=([user]=jiangxiaolong [age]=20 [sex]=boy)
userinfo+=([sy]=yunwei)
shuzu2=’([0]=“zero” [1]=“one” [2]=“two” [3]=“three” [4]=“four” [5]=“five” [6]=“six”)’
declare -a shuzu3=’([0]=“1” [1]=“2” [2]=“3” [3]=“4” [4]=“5” [5]=“6” [6]=“7” [7]=“linux shell” [20]=“tomcat”)
3.查看数组:
[root@localhost ~]# declare -a declare -a shuzu2='([0]="zero" [1]="one" [2]="two" [3]="three" [4]="four" [5]="five" [6]="six")' declare -a shuzu3='([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6" [6]="7" [7]="linux shell" [20]="tomcat")'
4.访问数组元数:
[root@localhost ~]# echo ${array1[0]} 访问数组中的第一个元数 [root@localhost ~]# echo ${array1[@]} 访问数组中的所有元数,等同于echo ${array1[*]} [root@localhost ~]# echo ${#array1[@]} 统计数组中元素的个数 [root@localhost ~]# echo ${!arrar2[@]} 获取数组元数的索引 [root@localhost ~]# echo ${array1[@]:1} 从数组下标1开始,也就是除了索引位0,其余都会显示 [root@localhost ~]# echo ${array1[@]:1:2} 从数组下标1开始,访问两个元素,也就是从索引1开始往后显示2个
5.案例
5.1数组的赋值及遍历
#!/bin/bash #-------------------数组的赋值及遍历------------------------- #20200217 while read line do hosts[++i]=$line #++i表示先运算在赋值,i默认为0,因此第一个i的值为1,如果是i++则是先赋值在运算,也就是第一个值为0 done </etc/hosts echo "hosts first: ${hosts[1]}" #输出数组中的第一个元数值 for i in ${!hosts[@]} #输出数组中的索引位,这是普通数组也就是1,2,3... do echo "$i: ${hosts[i]}" #${hosts[i]}中的i就是变量i,可以不加$符号,因为前面已经有了 done echo echo echo #----------------------------for实现数组的赋值及赋值------------------------ OLD_IFS=$IFS #定义之前已经设置好的IFS分隔符,默认以空格分隔 IFS=$'\n' #定义新的分隔符,以换行为准 for line in `cat /etc/hosts` do hosts[j++]=$line #j++,先赋值在运算,从0开始 done for e in ${!hosts[@]} do echo "$e: ${hosts[e]}" done IFS=$OLD_IFS #仅给某一段更改分隔符,下面的代码不需要更换换行符,因此在这里换回来
5.2统计性别出现的次数
统计某一个文件中某种类型出现的次数
实现方法:把要统计的对象作为数组的索引,把它的值没出现一次就累加1
定义一个关联数组
declare -A sex
sex=([boy]=1) 将索引为boy的元数值设置为1
sex+=([girl]=1) 在sex数组中新增一个元数,并将索引为gril的元数值设置为1
let sex[boy]++ 将索引位boy的元数值每次加1
let sex[qt]++ 这种方法也可以增加一个元数,但是值只能是数字,如果想其他值可以用sex+=的方式设置
#!/bin/bash declare -A sex while read line do index=$(echo $line | awk '{print $1}' 获取索引位 let sex[index]++ 每当index被赋值后,对应的索引位boy\gril的元数值每次加1,默认是0,加的是元数值而不是新的元数 done <sex.txt for i in ${!sex[@]} do echo "$i: ${sex[$i]}" 注意在i前面加上$ done 输出结果 girl: 4 boy: 3
5.3统计不同类型的shell数量
#!/bin/bash #-------------------统计不同类型的shell数量------------------ #20200218 declare -A shells while read line do index=`echo $line |awk -F ":" '{print $NF}'` #读到每行的最后一列赋给索引 let shells[$index]++ #默认元数值为1,每当读到一样的索引位时元数值就加1 done < /etc/passwd for i in ${!shells[@]} #取出索引位 do echo "$i: ${shells[$i]}" done
5.4统计tcp连接状态的数量
方法1,使用watch不停执行 watch -n1 ./count_tcp.sh #!/bin/bash #-----------------------统计tcp连接状态数量----------------------- declare -A status index_type=`ss -an | awk '{print $2}'` for i in $index_type do let status[$i]++ done for j in ${!status[@]} do echo "$j: ${status[$j]}" done 方法2,使用while循环执行不停执行 #!/bin/bash #-----------------------统计tcp连接状态数量----------------------- while : do unset status declare -A status index_type=`ss -an | awk '{print $2}'` for i in $index_type do let status[$i]++ done for j in ${!status[@]} do echo "$j: ${status[$j]}" $j前面必须加$否则会读不到数 done sleep 1;clear done