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[@]}查看数组中的所有值,echo array[@]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