Shell-数组-实例


title: Shell-数组-实例
date: 2020-05-05 16:51:18
categories:

  • Shell
    tags:
  • 数组

欢迎访问我的博客:https://nothingzh.gitee.io/
Nothingzh的博客

一.数组分类

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

多用于对变量切片

1.变量

使用数组进行切割

定义一个变量name=zxy,取得中间的x,就需要使用数组echo "${name:0}"

2.普通数组

只能使用整数0 1 2,作为数组索引

echo "${book[0]}"等于数组中的第一个数nginx

3.关联数组

可以使用字符串,作为数组索引

  • 定义关联数组,申明是关联数组
  • 关联数组declare -A [数组名],
  • 定义关联数组tt=([index1]=test [index2]=test2)。index1为索引值,test为内容
  • 查看数组内容
#echo ${tt[@]}
test test2

若未提前关联数组,此时查看数组内容则只输出test2

#echo "${tt[@]}"
test2
  1. 查看索引下标
#echo ${!tt[@]}
index1 index2

// 每个索引进行单个赋值,流程如下:

# array1[0]=pear
# array1[1]=apple
# array1[2]=orange
# array1[3]=peach
# echo ${array1[@]}
	pear apple orange peach
# echo ${array1[1]}
	apple

// 一次赋值多个值,流程如下:

索引=下标

[root@localhost ~]# arrary2=(tom jack alice)
[root@localhost ~]# echo ${!arrary2[@]}
0 1 2
[root@localhost ~]# echo "${arrary2[0]}"
tom

分号""赋值:
[root@localhost ~]# arrary3=(tom jack alice "mike jordan")  
[root@localhost ~]# echo "${arrary3[@]}"
tom jack alice mike jordan
[root@localhost ~]# echo "${!arrary3[@]}"
0 1 2 3
 #分号内为一个赋值,“mike jordan”是一个整体
[root@localhost ~]# echo "${arrary3[3]}"
mike jordan

 
定义索引(下标)名称
[root@localhost ~]# array4=(1 2 3 "a and b" [20]=world)
[root@localhost ~]# echo "${array4[@]}"
1 2 3 a and b world
查看数组的索引名,会出现个20,而不是4。因为20为自定义,直接跳到20
[root@localhost ~]# echo "${!array4[@]}"
0 1 2 3 20
[root@localhost ~]# echo "${array4[3]}"
a and b
查看自定义索引名的内容,[20]=world
[root@localhost ~]# echo "${array4[20]}"
world

//将/etc/passwd文件中的每一行作为元数赋值给数组 array5

[root@localhost ~]# cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
......省略
[root@localhost ~]# array5=(`cat /etc/passwd`)
[root@localhost ~]# echo "${array5[0]}"
root:x:0:0:root:/root:/bin/bash
[root@localhost ~]# echo "${array5[1]}"
bin:x:1:1:bin:/bin:/sbin/nologin

//循环数组的 索引key,并循环数组的 内容value

i++ 例如int i=1,a=0; a=i++; ---->a=i;---->a=a+1;----->a=1

[root@nothingzh shell]# bash hosts_array.sh
#!/bin/bash

#declare -A hosts_array
#1.对数组进行赋值,定义索引,$line赋值到内容
while read line
do
                hosts_array[++i]=$line  #++i用于先运算等1,循环后+1
				# $line用于读入/etc/hosts的每一行内容
done </etc/hosts
echo "first的索引值是: ${hosts_array[1]}"
#2.对数组进行遍历循环,分别输出索引对应的内容
#	${!hosts_array[*]}=1 2 3 因为/etc/hosts文件中只有3行
for j in ${!hosts_array[*]}  #${!hosts_array[*]}获取数组的索引,下方echo配合j的变量输出1 2 3 索引下的内容
do
        echo "索引是:$j,hosts的内容:${hosts_array[$j]}"
done

4.查看数组赋值结果

可理解为[key]=“value”

[root@localhost ~]# declare -a
declare -a BASH_ARGC='()'
declare -a arrary2='([0]="tom" [1]="jack" [2]="alice")'
declare -a arrary3='([0]="tom" [1]="jack" [2]="alice" [3]="mike jordan")'
declare -a array4='([0]="1" [1]="2" [2]="3" [3]="a and b" [20]="world")'
declare -a array5='([0]="root:x:0:0:root:/root:/bin/bash" [1]="bin:x:1:1:bin:/bin:/sbin/nologin" [2]="daemon:x:2:2:daemon:/sbin:/sbin/nologin" 
....

5.数组的常见用法

#号为统计个数符号
*,@ 为访问所有元素
! 为获取数组的索引

统计数组个数
[root@localhost ~]# array3=(tom jack alice "mike jordan")
[root@localhost ~]# echo "${#array3[@]}"
4

访问数组的第一个元素
[root@localhost ~]# echo "${array3[0]}"
tom
从索引1开始,向后访问
[root@localhost ~]# echo "${array3[@]:1}"
jack alice mike jordan
从索引1开始,向后访问2个元素
[root@localhost ~]# echo "${array3[@]:1:2}"
jack alice

6.数组案例

6.1 统计文件中男m,女f,小动物x 共有多少

// 常规linux命令统计, 统计男m,女f,动物x 共有多少

创建一份测试数据

# cat >> name-sex.txt <<EOF
NAME SEX
qwe m
zxc m
rty f
fgh f
zjz m
bnm f
gg x
asd m
mm x
EOF

awk:过滤第二行,sort:排序,uniq -c:用于统计数量

# awk -F' ' '{print $2}' name-sex.txt | sort |uniq -c
      3 f
      4 m
      2 x

// 使用数组统计, 统计男m,女f,小动物x 共有多少

[root@nothingzh shell]# bash array_tongji.sh
#!/bin/bash
#统计name_sex.txt 男m,女f,小动物x 共有多少
# v1.0 by zjz 2020-05-03

#!!!统计字符必须使用到关联数组!!!
declare -A array_count
#1.对关联数组进行赋值
while read line
do
		#获取到name-sex.txt中的m、f、x
        sex=$(echo $line | awk -F' ' '{print $2}')
        let array_count[$sex]++  #当索引中m有一个是+1,
#       echo ${array_count[*]}

done < /root/shell/name-sex.txt

#2.对关联数组进行遍历循环,分别输出索引对应的内容
#	这里的i=m、f、x. ${!array_count[*]}用于取出索引
for i in ${!array_count[*]}
do
        echo "索引名称:$i,索引所对应个数:${array_count[$i]}"
done

查看执行过程

+ read line                  #读一行
++ echo qwe m                #此行是姓名:qwe  性别:m   
++ awk '-F ' '{print $2}'    #只取m
+ sex=m		                 #索引sex=m 赋值为m
+ let 'array_count[m]++'     #这里的array_count[m]++ 
++++ 		现在echo ${array_count[m]} ,它就等于1 
-------------
+ read line   
++ echo fgh f
++ awk '-F ' '{print $2}'
+ sex=f
+ let 'array_count[f]++'   #这里的array_count[f]++ 
+ read line
++++ 		现在echo ${array_count[f]} ,它就等于1 

整体执行结果:

[root@nothingzh shell]# bash array_tongji.sh
索引名称:f,索引所对应个数:3
索引名称:m,索引所对应个数:4
索引名称:x,索引所对应个数:2
6.2使用数组统计/etc/passwd中/bin/bash/bin/sync等等的用户有几个。

注意! /etc/passwd文件中的halt、shutdown用户。会导致在你不经意的情况下关机

测试脚本时不建议直接对/etc/passwd文件进行操作。
创建测试文件:
#cp /etc/passwd /root/

[root@localhost ~]# cat /root/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
..........

// 使用常规命令passwd文件的执行shell进行统计。

[root@localhost ~]# cat /root/passwd | awk -F':' '{print $NF}' | sort | uniq -c
      4 /bin/bash
      1 /bin/sync
     14 /sbin/nologin
      1 /sbin/qqqq
      1 /sbin/wwwwwww

//使用数组进行统计/bin/bash/bin/sync等等的用户有几个

[root@localhost ~]# cat array_count_bash.sh
#!/bin/bash
#用户/etc/passwd 文件/bin/bash等等的用户名有多少个
#v1.0 by zjz 2020-05-04

#1.数组中的索引用到字符的,必须先声明为关联数组
declare -A array_count_bash
#2.对关联数组用的 索引  进行赋值
while read line
do
        shell=$(echo $line|awk -F':' '{print $NF}')
        let array_count_bash[$shell]++   #索引 赋值后 ++ 进行自加1
done < /root/passwd
#3. 对关联数组进行遍历循环,分别输出索引对应的内容
#$i = ${!array_count_bash[$i]} = /bin/bash /sbin/nologin 等等
#${array_count_bash[*]}  = 14 1 1 1 4
for i in ${!array_count_bash[*]}    #${!array_count_bash[*]}  !用于取得索引
do
        echo "suoying-name:$i ====> suoying-count:${array_count_bash[$i]}"
done

执行结果:

[root@localhost ~]# bash  array_count_bash.sh
suoying-name:/sbin/nologin ====> suoying-count:14
suoying-name:/sbin/qqqq ====> suoying-count:1
suoying-name:/sbin/wwwwwww ====> suoying-count:1
suoying-name:/bin/sync ====> suoying-count:1
suoying-name:/bin/bash ====> suoying-count:4
6.3 统计当前主机ss -an 的监听状态

//使用常规Linux命令统计
# ss -an | awk '{print $2}' | sort | uniq -c
执行结果

[root@localhost ~]# ss -an | awk '{print $2}' | sort | uniq -c
     91 ESTAB
     35 LISTEN
      1 State
     67 UNCONN

//使用关联数组统计当前主机ss -an 的监听状态

[root@localhost ~]# cat array_status.sh
#!/bin/bash
# 统计当前主机ss -an 的监听状态
# v1.0 by zjz 2020-05-05
#1.数组中的索引用到字符的,必须先声明为关联数组
declare -A array_state
#2.获取索引      统计的**对象**
state=$(ss -an | awk '{print $2}')
#3.对统计的**对象**进行累加
for i in $state
do
        let array_state[$i]++
done
#4.对关联数组进行遍历循环,分别输出索引对应的内容
for j in ${!array_state[*]}
do
        echo "STATUS: $j, STATUS Count:${array_state[$j]}"
done

执行结果:#watch -n1 bash array_status.sh 每1s刷新一次结果

[root@localhost ~]# bash array_status.sh
STATUS: ESTAB, STATUS Count:91
STATUS: UNCONN, STATUS Count:67
STATUS: State, STATUS Count:1
STATUS: LISTEN, STATUS Count:35

运用实例:

  • 统计文件中男m,女f,小动物x 共有多少个
  • 统计/etc/passwd中/bin/bash/bin/sync等等的用户有几个。

总结上面实例 关联数组:
- 数组中的索引用到字符的,必须先声明为关联数组
- array_test={ [索引] =内容}
--------------------------------------
* | @ 为访问所有元素
! 为获取数组的索引
---------------------------------------
- 索引 统计的对象
- 内容 统计名称的数量
---------------------------------------
- 处理文件对用while read line 取索引对象
- 程序运行结果用for进行循环统计

[root@localhost ~]# declare -A array_test
[root@localhost ~]# array_test=([zjz]=pt [zxy]=pt [xyx]=zz)
[root@localhost ~]# echo ${array_test[*]}
pt zz pt
[root@localhost ~]# echo ${!array_test[*]}
zjz xyx zxy

更多更好的原创文章,请访问官方网站: 点我就能跳转咯-》https://nothingzh.gitee.io
也可关注“哎呦运维”微信订阅号,随时接受文章推送。

猜你喜欢

转载自blog.csdn.net/qq_37126850/article/details/105892170