Shell数组

索引数组:只能使用整数作为数组索引
关联数组:可以使用字符串作为数组索引

索引数组

数组的定义

语法:数组名[下标]=变量值
方法一:

array=(Centos Ubuntu Deepin Redhat Fedora Arch "linux windows" [20]=system)

[root@localhost ~]# echo ${array[@]}
Centos Ubuntu Deepin Redhat Fedora Arch linux windows system

方法二:

array[0]=Centos
array[1]=Ubuntu
array[2]=Deepin
array[3]=Redhat
array[4]=Fedora
array[5]=Arch

[root@localhost ~]# echo ${array[@]}
Centos Ubuntu Deepin Redhat Fedora Arch

方法三:

# 动态定义数组变量,并使用命令的输出结果作为数组的内容
[root@localhost ~]# array=(`cat /root/Code/ip.txt`)
[root@localhost ~]# echo ${array[@]}
192.168.1.11 192.168.1.22 192.168.1.2 192.168.1.33

[root@localhost ~]# array=(`ls /root/`)
[root@localhost ~]# echo ${array[@]}
add100.sh anaconda-ks.cfg Code initial-setup-ks.cfg 公共 模板 视频 图片 文档 下载 音乐 桌面

colors=($red $blue $green $blaic $orange $yellow $recolor)

关联数组

数组的定义

[root@localhost ~]# declare -A info     # 关联数组必须要首先声明
[root@localhost ~]# info=([name]=Shuai [sex]=boy [age]=23 [height]=175)
[root@localhost ~]# echo ${info[name]}
Shuai
[root@localhost ~]# echo ${info[sex]}
boy
[root@localhost ~]# echo ${info[age]}
23
[root@localhost ~]# echo ${info[height]}
175

访问数组元素

# 其中@和*的作用相同,均是打印出所有元素
[root@localhost ~]# array=(Centos Ubuntu Deepin Redhat Fedora Arch "linux windows" [20]=system)

[root@localhost ~]# echo ${array[0]}        # 访问数组中的第一个元素
Centos

[root@localhost ~]# echo ${array[-1]}       # 访问数组中的最后一个元素
system

[root@localhost ~]# echo ${array[@]}        # 访问数组中的所有元素
Centos Ubuntu Deepin Redhat Fedora Arch linux windows system

[root@localhost ~]# echo ${array[*]}        # 访问数组中的所有元素
Centos Ubuntu Deepin Redhat Fedora Arch linux windows system

[root@localhost ~]# echo ${array[@]:3}      # 访问数组中从第3个到最后一个元素
Redhat Fedora Arch linux windows system

[root@localhost ~]# echo ${array[@]:0:3}        # 访问数组中前3个元素
Centos Ubuntu Deepin

打印数组个数

[root@localhost ~]# echo ${#array[@]}
8

[root@localhost ~]# echo ${#array[*]}
8

打印数组元素索引

[root@localhost ~]# echo ${!array[@]}
0 1 2 3 4 5 6 20

[root@localhost ~]# echo ${!array[*]}
0 1 2 3 4 5 6 20

数组的赋值

# 如果下标不存在,则自动添加一个新的元素,如果存在,则覆盖原来的值
[root@localhost ~]# array[7]=Mint
[root@localhost ~]# echo ${array[@]}
Centos Ubuntu Deepin Redhat Fedora Arch linux windows Mint system

[root@localhost ~]# array[0]=Kali
[root@localhost ~]# echo ${array[@]}
Kali Ubuntu Deepin Redhat Fedora Arch linux windows Mint system

数组的删除

[root@localhost ~]# unset array[1]
[root@localhost ~]# echo ${array[@]}
Kali Deepin Redhat Fedora Arch linux windows Mint system
[root@localhost ~]# 
[root@localhost ~]# unset array 
[root@localhost ~]# echo ${array[@]}

遍历数组

例1:遍历脚本内数组

#!/bin/bash
array=(Centos Ubuntu Deepin Redhat Fedora Arch linux windows Mint syste [20]=test)
echo ${!array[@]}
echo

for i in ${!array[@]}
do
        echo "$i:${array[i]}"
done

执行结果:

[root@localhost Code]# bash ./array_test.sh 
0 1 2 3 4 5 6 7 8 9 20

0:Centos
1:Ubuntu
2:Deepin
3:Redhat
4:Fedora
5:Arch
6:linux
7:windows
8:Mint
9:syste
20:test

例2:将文件内容转换成数组进行遍历

!/bin/bash
while read line
do
        hosts[i++]=$line
done < /etc/hosts

echo "hosts first:${hosts[1]}"
echo

for i in ${!hosts[@]}
do
        echo "$i:${hosts[i]}"
done

运行结果

hosts first:::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

0:127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
1:::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

例1:性别统计

创建需要统计的文件

[root@shuai test]# vim sex.txt
Shuai   boy
San     girl
si      girl
wu      girl
liu     boy
qi      girl
ba      boy
jiu     girl

1)数组方式
编写脚本

[root@shuai test]# vim count_sex.sh

#!/bin/bash
declare -A sex
while read line
do
        type=`echo $line | awk '{print $2}'`
        let sex[$type]++
done < sex.txt

for i in ${!sex[@]} 
do
        echo "$i:${sex[$i]}"
done

运行结果

[root@shuai test]# chmod a+x count_sex.sh
[root@shuai test]# ./count_sex.sh
girl:5
boy:3

2)awk方式

[root@shuai test]# awk '{print $2}' sex.txt | sort | uniq -c
3 boy                                                                5 girl

例2:统计不同类型的Shell

1)数组方式

#!/bin/bash
declare -A shell
while read line
do
        type=`echo $line | awk -F: '{print $NF}'`
        let shells[$type]++
done < /etc/passwd

for i in ${!shells[@]}
do
        echo "$i:${shells[$i]}"
done

运行结果

sbin/nologin:22
/bin/sync:1
/bin/bash:2
/sbin/shutdown:1
/sbin/halt:1

2)awk方式

[root@shuai test]# awk -F: '{print $NF}' /etc/passwd | sort | uniq -c      2 /bin/bash                                                          1 /bin/sync                                                          1 /sbin/halt                                                        22 /sbin/nologin                                                      1 /sbin/shutdown

例3:统计tcp状态连接数

[root@shuai test]# vim count_tcp_status.sh

#!/bin/bash
type=`ss -an | grep :80 | awk '{print $2}'`
declare -A status
for i in $type
do
       let status[$i]++
done

for j in ${!status[@]}
do
       echo "$j:${status[$j]}"
done

执行结果

[root@shuai test]# ./count_tcp_status.sh
ESTAB:2
TIME-WAIT:1
LISTEN:1

持续显示状态变化(需要借助watch命令)

[root@shuai test]# watch -n1 -d ./count_tcp_status.sh

Every 1.0s: ./count_tcp_status.sh                      Fri Apr 24 17:21:02 2020ESTAB:1
TIME-WAIT:9
LISTEN:1

或者使用无限循环来实现显示实时状态(但是会闪屏)

#!/bin/bash
while :
do
        unset status
        declare -A status
        type=`ss -an | grep :80 | awk '{print $2}'`

        for i in $type
        do
                let status[$i]++
        done

        for j in ${!status[@]}
        do
                echo "$j:${status[$j]}"
        done

        sleep 1
        clear
done
Last modification:July 23rd, 2020 at 04:16 pm
如果觉得我的文章对你有用,请随意赞赏