awk基本用法、处理条件、awk应用案例、监控脚本编写

Top

NSD SHELL DAY05

  1. 正则表达式补充
  2. sed补充
  3. 案例1:使用awk提取文本
  4. 案例2:awk处理条件
  5. 使用awk统计网站访问量
  6. 案例3:awk数组
  7. 案例4:awk扩展应用
  8. 案例5:安全检测
  9. 案例6:编写监控脚本

1 正则表达式补充

\w 匹配数字、字母、下划线

  1. egrep "roo\w" user #找roo后面必须是数字或字母或下划线的字符串

\s 匹配空格、tab键

  1. egrep "roo\s" user #找roo后面是1个空格或者tab键打出来的空格的字符串,如果没有
  2. 就不输出

\d 匹配数字,和[0-9]等效

  1. egrep "(25[0-5]\.|2[0-4][0-9]\.|1?[0-9]?[0-9]\.){3}(25[0-5]|2[0-4][0-9]|1?[0-9]?[0-9])" #匹配ip地址

  1. grep -P "(25[0-5]\.|2[0-4]\d\.|1?\d?\d\.){3}(25[0-5]|2[0-4]\d|1?\d?\d)" #匹配ip地址

2 sed补充

a行下追加 i行上添加 c替换整行

  1. sed 'a 666' user #所有行的下面追加666
  2. sed '1a 666' user #第1行的下面追加666
  3. sed '/^bin/a 666' user #在以bin开头的行的下面追加666
  4. sed 'i 666' user #所有行的上面添加666
  5. sed '5i 666' user #第5行的上面添加666
  6. sed '$i 666' user #最后1行的上面添加666
  7. sed 'c 666' user #所有行都替换成666
  8. sed '1c 666' user #替换第1行为666

替换特殊用法

  1. cat abc.txt                                #先准备素材
  2. 100 laowang
  3. 98 gangge
  4. 59 laoniu
  5. sed -r 's/([0-9]+)(\s+)([a-z]+)/\3\2\1/' abc.txt    #使用替换功能更改文本列,此处小括号相当于保留(复制),\1相当于粘贴之前第1个小括号里的内容

3 案例1:使用awk提取文本

3.1 问题

本案例要求使用awk工具完成下列过滤任务:

  • 练习awk工具的基本用法
  • 提取本机系统数据
  • 格式化输出信息

3.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:awk的基本用法

1)基本操作方法

格式1:awk [选项] '[条件]{指令}' 文件

格式2:前置指令 | awk [选项] '[条件]{指令}'

其中,print 是最常用的编辑指令;若有多条编辑指令,可用分号分隔。

Awk过滤数据时支持仅打印某一列,如第2列、第5列等

处理文本时,默认将空格、制表符作为分隔符。

条件可以用/ /的方式,与sed类似

awk常用内置变量:

$0 文本当前行的全部内容

$1 文本的第1列

$2 文件的第2列

$3 文件的第3列,依此类推

NR 文件当前行的行号

NF 文件当前行的列数(有几列)

  1. [root@svr5 ~]# cat abc.txt
  2. hello the world
  3. welcome to beijing
  4. awk '{print}' abc.txt                #输出所有
  5. awk '/to/{print}' abc.txt            #输出有to的那行
  6. awk '{print $2}' abc.txt            #输出所有行的第2列
  7. awk '/to/{print $1}' abc.txt        #输出有to的那行的第1列
  8. awk '{print $0}' abc.txt            #输出所有行所有列
  9. awk '{print $0,$1}' abc.txt        #输出所有行所有列,第1列
  10. awk '{print NR}' abc.txt            #输出所有行的行号
  11. awk '{print NR,$0}' abc.txt        #输出所有行的行号,所有列
  12. awk '{print NR,NF}' abc.txt        #输出所有行的行号,列号(有几列)

再使用之前的user文档测试

  1. awk '/^bin/{print NR}' user        #找以bin开头的行,显示该行的行号
  2. awk '/^bin/{print NR,$0}' user    #找以bin开头的行,显示该行的行号,所有列
  3. awk '{print NF}' user            #输出所有行的列号(每行有几列)

2)选项 -F 可指定分隔符

  1. awk -F: '{print $1}' user         #文档中如果没有空格,可以用F修改分隔符
  2. awk -F: '{print $1,$6}' user        #使用冒号作为列的分隔符,显示第1、6列

awk还识别多种单个的字符,比如以“:”或“/”分隔

  1. awk -F [:/] '/^root/{print $1,$10}' user

awk的print指令不仅可以打印变量,还可以打印常量

  1. awk -F: '{print $1" 的家目录是 "$6}' user #输出常量,加双引号即可
  2. awk -F: '{print $1" 的解释器是 "$7}' user

步骤二:利用awk提取本机系统数据

1)收集根分区剩余容量

  1. df -h | awk '/\/$/{print $4}' #使用df -h 作为前置指令交给awk处理找到以/结尾的行,并输出第4列
  2. df -h | awk '/\/$/{print "根分区剩余容量是"$4}' #然后加常量输出

2)收集网卡流量信息

RX为接收的数据量,TX为发送的数据量。packets以数据包的数量为单位,bytes以字节为单位:

  1. ifconfig eth0 | awk '/RX p/{print "eth0网卡接收的数据量是"$5"字节"}'
  2. ifconfig eth0 | awk '/TX p/{print "eth0网卡发送的数据量是"$5"字节"}'

步骤三:格式化输出信息

1)awk处理的时机

awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。在命令格式上分别体现如下:

  1. awk [选项] '[条件]{指令}' 文件
  2. awk [选项] 'BEGIN{指令} {指令} END{指令}' 文件
  • BEGIN{ } 行前处理,读取文件内容前执行,指令执行1次
  • { } 逐行处理,读取文件过程中执行,指令执行n次
  • END{ } 行后处理,读取文件结束后执行,指令执行1次
  1. awk -F: 'BEGIN{print "start"}{print $1}END{print "over"}' user
  2. awk 'BEGIN{print NR}{print NR}END{print NR}' user

2)格式化输出/etc/passwd文件

要求: 格式化输出passwd文件内容时,要求第一行为列表标题,中间打印用户的名称、UID、家目录信息,最后一行提示一共已处理文本的总行数,效果如图-1所示。

3)根据实现思路编写、验证awk过滤语句

输出信息时,可以使用“\t”显示Tab制表位:

  1. awk 'BEGIN{print "User\tUID\tHome"}'            #第1步输出表头信息
  2. awk -F: '{print $1"\t"$3"\t"$6}' user            #第2步输出内容
  3. awk 'END{print "总计"NR"行" }' user                #第3步输出结尾
  4. awk -F: 'BEGIN{print "User\tUID\tHome"}{print $1"\t"$3"\t"$6}END{print "总计"NR"行"}' user #合在一起写

 

4 案例2:awk处理条件

4.1 问题

  • 本案例要求使用awk工具熟悉各种条件,以达到更精确查找某行的目的

4.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:认识awk处理条件的设置

使用正则设置条件

/正则/ ~ 包含 !~不包含

  1. awk -F: '$6~/root/{print}' user #输出第6列包含root的行
  2. awk -F: '$6~/bin/{print}' user #输出第6列包含bin的行
  3. awk -F: '$6!~/bin/{print}' user #输出第6列不包含bin的行

2)使用数值/字符串比较设置条件

比较符号:==(等于) !=(不等于) >(大于)

>=(大于等于) <(小于) <=(小于等于)

  1. awk -F: '$3<3{print}' user            #输出第3列小于3的行
  2. awk -F: '$3<=3{print}' user        #输出第3列小于等于3的行
  3. awk -F: 'NR==2{print}' user        #输出第2行
  4. awk -F: 'NR>2{print}' user            #输出行号大于2的行

3)逻辑测试条件

  1. awk -F: 'NR>=3&&NR<=5{print}' user            #找行号是3~5行
  2. awk -F: 'NR==2||NR==4{print}' user            #找行号是2或者4的行
  3. awk -F: 'NR==2||NR==40{print}' user        #如果只有一个条件满足就显示一个

当定义了条件且指令就是print时可以省略指令不写

  1. awk -F: '$7~/bash/&&$3<=500' user        #找第7列包含bash并且第3列小于等于500的行
  2. awk 'NR==2&&NR==4' user                #找行号既是2又是4的行,不存在,无输出
  3. awk -F: '$7~/bash/&&NR<=3' user        #找第7列包含bash并且行号是1~3的
  4. awk -F: '$7~/bash/||NR<=3' user        #找第7列包含bash或者行号是1~3的

4)数学运算

  1. awk 'NR%2==0{print NR,$0}' user #在条件中使用运算,找到将行号除以2余数等于0的行,然后输出该行的行号和所有列,相当于输出偶数行

5 使用awk统计网站访问量

使用awk统计网站访问量

  1. setenforce 0                         #关闭selinux
  2. systemctl stop firewalld            #关闭防火墙
  3. systemctl restart httpd            #开启网站服务

使用浏览器多访问几次网站,包括本机用curl

  1. curl 192.168.88.2:82                #如果端口没改过就不用敲:82
  2. awk '{print $1}' /var/log/httpd/access_log #初步统计,不完美

6 案例3:awk数组

6.1 问题

本案例要求了解awk数组的使用

步骤一:awk数组

1)数组的语法格式

数组是一个可以存储多个值的变量,具体使用的格式如下:

定义数组的格式:数组名[下标]=元素值

调用数组的格式:数组名[下标]

  1. awk 'BEGIN{a=10;a=20;print a}'                 #首先测试普通变量
  2. awk 'BEGIN{a[1]=10;a[2]=20;print a[2],a[1]}' #使用awk测试数组,创建数组a,下标1对应值是10,下标2对应值是20,然后输出下标是2与下标是1的值

注意,awk数组的下标除了可以使用数字,也可以使用字符串,字符串需要使用双引号:

  1. awk 'BEGIN{a["abc"]="abcabc";a["xyz"]="xyzxyz";print a["xyz"]}'

以上信息是手工输入,还可以从文档收集

准备一个测试文档,里面有6行,每行分别是abc、xyz、abc、opq、xyz、abc 然后按照awk逐行处理的工作特点使用awk '{a[$1]++}' shu.txt 走完每一行得到下列结果,但不会输出到屏幕

逐行任务 每行实际执行 执行结果

a[$1]++   a[abc]++   a[abc]=1

a[$1]++   a[xyz]++   a[xyz]=1

a[$1]++   a[abc]++   a[abc]=2

a[$1]++   a[opq]++   a[opq]=1

a[$1]++   a[xyz]++   a[xyz]=2

a[$1]++   a[abc]++   a[abc]=3

  1. awk '{a[$1]++}END{print a["abc"]}' shu.txt     #如果要看值,可以输出数组名[下标],由于数组下标不确定,逐行任务运算前可以不用BEGIN任务定义

根据上述操作了解数组可以收集信息,但收集完了之后查看确不方便,可以用for循环实现。方法如下:

for(变量名 in 数组名){print 变量名} #这个格式可以查看数组的所有下标

  1. awk '{a[$1]++}END{for(i in a){print i,a[i]}}' shu.txt #使用逐行任务与数组收集文档shu.txt中的信息,然后在END任务中使用for循环显示所有数组a的下标与值

7 案例4:awk扩展应用

7.1 问题

本案例要求使用awk工具完成下列两个任务:

分析Web日志的访问量排名,要求获得客户机的地址、访问次数,并且按照访问次数排名

7.2 方案

1)awk统计Web访问排名

在分析Web日志文件时,每条访问记录的第一列就是客户机的IP地址,其中会有很多重复的IP地址。因此只用awk提取出这一列是不够的,还需要统计重复记录的数量并且进行排序。

通过awk提取信息时,利用IP地址作为数组下标,每遇到一个重复值就将此数组元素递增1,最终就获得了这个IP地址出现的次数。

针对文本排序输出可以采用sort命令,相关的常见选项为-r、-n、-k。其中-n表示按数字顺序升序排列,而-r表示反序,-k可以指定按第几个字段来排序。

7.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:统计Web访问量排名

分步测试、验证效果如下所述。

1)提取IP地址及访问量

  1. awk '{ip[$1]++}END{for(i in ip){print ip[i],i }}' /var/log/httpd/access_log #数组名称可以自定义其他的,通过awk数组+for循环查看日志中哪个ip来访过以及来访的次数

2)对第1)步的结果根据访问量排名

  1. awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' /var/log/httpd/access_log | sort -nr        #使用sort命令增加排序功能,-n是以数字形式排序,-r是降序

8 案例5:安全检测

8.1 问题

本案例要检测登录者的IP

检测安全日志,登录root且密码错误就输出对方IP

8.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:准备工作

1)/var/log/secure是安全日志,如果有人登陆时输入错误密码的话信息会记录下来,这种信息可以用awk抓取出来,方法如下:

  1. awk '/Failed password for root/{ip[$11]++}END{for(i in ip){print i,ip[i]}}' /var/log/secure #统计安全日志中访问root账户且密码输入错误的ip地址与次数

9 案例6:编写监控脚本

9.1 问题

本案例要求编写脚本,实现计算机各个性能数据监控的功能,具体监控项目要求如下:

9.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:准备工作

1)部分常用命令

  1. [root@svr5 ~]# uptime                            #查看CPU负载
  2. [root@svr5 ~]# ifconfig eth0                    #查看网卡流量
  3. [root@svr5 ~]# free                            #查看内存信息
  4. [root@svr5 ~]# df                                #查看磁盘空间
  5. [root@svr5 ~]# wc -l /etc/passwd                #查看计算机账户数量
  6. [root@svr5 ~]# who |wc -l                        #查看登录账户数量
  7. [root@svr5 ~]# rpm -qa |wc -l                    #查看已安装软件包数量

步骤二:编写参考脚本

1)脚本内容如下:

  1. #!/bin/bash
  2. while :
  3. do
  4. clear                                    #清屏
  5. free -h | awk '/^Mem:/{print "剩余内存容量是"$4}'
  6. df -h | awk '/\/$/{print "根分区剩余容量是"$4}'
  7. awk 'END{print "用户总数是"NR"个"}' /etc/passwd
  8. who | awk 'END{print "登录用户数量是"NR"个"}'
  9. uptime | awk '{print "cpu的15分钟平均负载是"$NF}'
  10. rpm -qa | awk 'END{print "安装的软件包数量是"NR"个"}'
  11. sleep 3
  12. done

 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值