shell数组
- 数组基本概述
- 什么是数组
- 数组的分类
- 普通数组
- 关联数组
 
- 数组的遍历与循环
- 案例1:
- 案例2:
- 案例3:
- 案例4:
 
 
 
 
数组基本概述
什么是数组
数组其实也算是变量,传统的变量只能存一个值,但是数组可以存多个值。
实际使用中主要通过for循环遍历数组中的数据
 在awk、zabbix低级自动发现会使用到
数组的分类
shell数组分为普通数组和关联数组
 普通数组:只能使用整数 作为数组索引
 关联数组:可以使用字符串作为数组索引
普通数组
定义普通数组格式:数组名=(值1 值2 值3)
 或
 数组名[索引]=xxx
 books[0]=python
 books[1]=java

索引是从0开始的
 
 直接当变量输出,只会打印一个值
 
 echo ${books[@]}  使用 @输出所有索引内容
 
 echo ${!books[@]}  加一个!输出所有的索引
 
books=(linux nginx python) #定义普通数组
echo ${books[1]} #输出指定索引内容,指定索引,得到索引的值
关联数组
定义关联数组格式:数组名=([索引]=值 [索引1]=值1 [索引2]=值2 )

关联数组定义之前需要先申明
 declare -A info
定义关联数组
 info=([name]=oldxu [age]=12 [skill]=linux [books]=python)
获取关联数组中的所有数据
 echo ${info[@]}
获取关联数组中的所有索引
 echo ${!info[@]}
获取关联数组中某一索引的值
 echo ${info[name]}

数组的遍历与循环
其实就是对数组进行批量赋值,然后通过循环的方式批量取出数组的值,对取出的内容进行统计。
例如需要统计一个文件中某个字段出现的次数
 思路就是:要统计谁,就将谁作为数组的索引,然后看它出现的次数,仅支持关联数组。
数组遍历的两种方式
 1.通过数组的个数进行遍历(不推荐)
 2.通过数组的索引进行遍历(推荐)
案例1:
#!/bin/bash
while read line #read line命令用于读取文件中的每一行,并将其存储在line变量中.
do
hosts[i++]=$line #数组赋值#每循环一次索引自增1次,将文件中对应行的内容赋值给数组的索引
done</tmp/hosts #读取/tmp/hosts文件
#将赋值步骤拆解开就是以下效果:
    #hosts[0]=127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
    #hosts[1]=::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
    #hosts[2]=
    #hosts[3]=10.0.10.10 www.test.com
#遍历数组
for i in ${!hosts[@]} #${!hosts[@]}数组hosts中的所有索引
do
echo "索引为:$i ,索引对应的值为:${hosts[$i]}"
done
脚本执行效果:
 
案例2:
使用关联数组统计文件中的男女性别
ck 男
alice 女
tom 男
rose 女
robin 男
sam 男
以性别作为key,出现次数作为value构建关联数组
#!/bin/bash
declare -A list #申明数组
while read line
do
gender=$(echo $line|awk '{print $2}') #获取到文件中每行的性别
#要统计性别,就将性别作为索引,然后让其出现相同性别的时候进行自增
let list[$gender]++
done</tmp/gender.txt
#遍历数组
for i in ${!list[@]}
do
echo "索引为:$i ,索引出现的次数为:${list[$i]}"
done
脚本执行效果:

使用awk实现性别统计的效果
 
使用常规的方法实现性别统计的效果
sort 排序
 uniq -c 在每行前面显示该行重复出现的次数

案例3:
统计/etc/passwd 中 Shell的类型,出现的次数。
常规方法获取:
 
awk的方法获取:
 
以shell类型作为key,出现次数作为value构建关联数组
#!/bin/bash
declare -A passwd #申明数组
while read line
do
type=$(echo $line|awk -F ':' '{print $7}') #获取到文件中每行的shell类型
#要统计shell类型,就将shell类型作为索引,然后让其出现相同shell类型的时候进行自增
let passwd[$type]++
done</etc/passwd
#遍历数组
for i in ${!passwd[@]}
do
echo "(索引)shell类型为:$i ,该类型出现的次数为:${passwd[$i]}"
done
脚本执行的效果:
 
案例4:
使用Shell数组,去统计nginx日志TOP的IP地址。
#!/bin/bash
declare -A accesslog #申明数组
while read line
do
ip=$(echo $line|awk '{print $1}') #获取到文件中每行的访问ip
#要统计ip,就将ip作为索引,然后让其出现相同ip的时候进行自增
let accesslog[$ip]++
done</etc/nginx/logs/access.log
#遍历数组
for i in ${!accesslog[@]}
do
echo "(索引)ip地址:$i ,访问的次数:${accesslog[$i]}"
done
脚本执行效果:
 
常规方法统计:
 cat /etc/nginx/logs/access.log |awk '{print $1}'|sort|uniq -c|sort -nr
sort 参数
 -n:对文件进行数字排序
 -r:按相反顺序排序
 
awk方法统计:
 awk '{ip[$1]++} END { for (i in ip) {print "IP地址:"i,"访问"ip[i] " 次"}}' /etc/nginx/logs/access.log
 



















