awk
awk数据处理引擎
•awk编程语言/数据处理引擎
•基于模式匹配检测输入文本,逐行处理并输出,获取指定的数据
•awk过滤数据时支持仅打印某一列,如:第2列、第4列...
•awk命令格式1:awk [选项] '条件1{指令} 条件2{指令}' 文件名(注意:'条件 {指令}'必须用单引号包起来)
•awk命令格式2:前置命令 | awk [选项] '条件{指令}'
•常用指令:print (是最常用的打印指令)
•常用选项:-F (指定分隔符,如果不指定,默认以空格或tab键作为分隔符,可以通过[]集合匹配多种单个分隔符)
•awk 内置变量:$1第一列,$2第二列,$3第三列...依次类推。NR文件当前行号,NF文件当前列数。.
•命令格式1演示:
#随意编辑一个文档 [root@localhost131 shcode]# cat testawk.sh hello the woman welcome to chinal #默认分隔符打印第一列和第三列 [root@localhost131 shcode]# awk '{print $1,$3}' testawk.sh hello woman welcome china #指定分割符 -F #手动指定:为分隔符,打印/etc/passwd [root@localhost131 shcode]# awk -F: '{print $1,$3}' /etc/passwd ... apache 48 harry 1014 dhcpd 177 mysql 27 zabbix 987 #指定不同的分隔符 [root@localhost131 shcode]# head -1 /etc/passwd #注意:/之间也算是一列 root:x:0:0:root:/root:/bin/bash [root@localhost131 shcode]# awk -F[:/] 'NR==1 {print $1,$10}' /etc/passwd root bash #条件可以为正则表达式,需要用//包起来 #正则过滤以tom开头的行 [root@localhost131 shcode]# awk -F: '/^tom/ {print}' /etc/passwd tom:x:1000:1003:tom:/home/tom:/bin/bash #打印文件每一行与每一行的列数 [root@localhost131 shcode]# awk -F: '{print NR,NF}' /etc/passwd #打印文件的每一行与每一行的列数 [root@localhost131 shcode]# awk -F: '{print NR,NF,$NF}' /etc/passwd #定义用户自定义的常量: [root@localhost131 shcode]# awk -F: '/^tom/ {print $1,"用户的解释器为:",$7}' /etc/passwd tom 用户的解释器为: /bin/bash #打印第一列为root的行 [root@localhost131 shcode]# awk -F: '$1~/root/' /etc/passwd root:x:0:0:root:/root:/bin/bash #排除第7列nologin的行,打印第一列和第七列 [root@localhost131 shcode]# awk -F: '$7!~/nologin/ {print $1,$7}' /etc/passwd #扩展正则 [root@localhost131 shcode]# awk -F: '/^(root/adm)/ {print $1,$7}' /etc/passwd root /bin/bash adm /sbin/nologin
•awk使用数值/字符串比较设置条件
•等于: ==
•不等于: !=
•大于: >
•大于于等于: >=
•小于:<
•小于等于:<=
#打印第三行 第七列 [root@localhost131 shcode]# awk -F: 'NR==3 {print $7}' /etc/passwd /sbin/nologin #awk做数值对比,打印文件中第三3列大于等于1000的第1列,第3列,第7列 [root@localhost131 shcode]# awk -F: '$3>=1000 {print $1,$3,$7}' /etc/passwd #打印文件中第3列大于500 小于1000的 [root@localhost131 shcode]# awk -F: '$3>500 && $3<1000 {print $1,$3,$7}' /etc/passwd #排除第一列为root的行 [root@localhost131 shcode]# awk -F: '&1!="root" {print $1,$3,$7}' /etc/passwd
•awk过滤时机:awk 'BEGIN{指令}{指令}END{指令}' 文件名
·BEGIN{指令} #读取文件内容之前执行指令,指令执行一次。
·{指令} #读取文件过程中执行,逐行执行。
·END{指令} #读取文件结束后执行指令,指令执行一次。
#加BEGIN行前处理 [root@localhost131 shcode]# awk 'BEGIN{print"正在处理中"}' 正在处理中 #定义变量 ;号作为分隔的,执行完前面的执行后面的 [root@localhost131 shcode]# awk 'BEGIN{x=10;print x}' 10 #四则运算 [root@localhost131 shcode]# awk 'BEGIN{x=10;print x+5}' 15 [root@localhost131 shcode]# awk 'BEGIN{x=10;print x*5}' 50 [root@localhost131 shcode]# awk 'BEGIN{x=10;print x-5}' 5 [root@localhost131 shcode]# awk 'BEGIN{x=10;print x/5}' 2 [root@localhost131 shcode]# awk 'BEGIN{print 10+5}' 15 #通过awk统计系统使用bash解释器的用户有多少个 [root@localhost131 shcode]# awk 'BEGIN{x=0} /bash$/{x++}END{print x}' /etc/passwd 13
•awk分支结构
•if单分支格式:{if(条件){指令}}
•if双分支格式:{if(条件){指令}else{指令}}
#if单分支统计passwd文件中UID大于或等于1000的用户个数 [root@localhost131 shcode]# awk -F: '{if($3>=1000){i++}}END{print i}' /etc/passwd 13 #if双分支统计passwd中UID大于等于1000的用户,和小于1000的用户个数 [root@localhost131 shcode]# awk -F: '{if($3>=1000){i++} else{x++}}END{print i,x}' /etc/passwd 13 46
•awk数组
•定义数组格式1:数组名[下标]=值
•定义数组格式2:数组名[下标]
•数组的用法:for(变量名 in 数组名){print 数组名[变量]}
#awk定义数组方式1 [root@localhost131 ~]# awk 'BEGIN{x[0]=10;x[1]=20;print x[0],x[1]}' 10 20 #awk定义数组方式2 [root@localhost131 ~]# awk 'BEGIN{x[0]++;print x[0]}' 1
•awk循环结构
•命令格式:for(变量名 in 数组名){print 数组名[变量]}
#当用awk对数组进行取值的时候i in a,取得并不是组数对应的值,而取的是数组的下标。 [root@localhost131 ~]# awk 'BEGIN{a[0]=00;a[1]=11;a[2]=22;for(i in a){print i,a[i]}}' 0 00 1 11 2 22
•awk命令格式2:前置命令 | awk [选项] ‘条件[指令]’
#查看剩余内存free -h [root@localhost131 ~]# free -h | grep 'Mem' | awk '{print $4}' 830M [root@localhost131 ~]# free -h | awk '/Mem/{print $4}' 830M #写一个监控脚本,监控网口进出口流量 #!/bin/bash while : do clear ifconfig ens33 | awk '/inet / {print "IP:",$6}' ifconfig ens33 | awk '/RX p/{print "入口流量:",$5,$6,$7}' ifconfig ens33 | awk '/TX p/{print "出口流量:",$5,$6,$7}' sleep 0.2 done
#写一个脚本监控/分区可用容量 #df -h / 查看根分区容量,awk'NR==2'得到7.3G,后面的awk以G为分隔符打印第一列为7.3 [root@localhost131 ~]df -h / | awk 'NR==2 {print $4}'|awk -FG '{print $1}' 7.3
查询根分区剩余空间和内存剩余
#!/bin/bash df -h | grep '/$' | awk '{print"根分区剩余空间:",$4}' free -h | grep Mem | awk '{print "物理内存剩余空间:",$4}'
·通过awk统计用户登录系统的次数
#定义一个数组ip,把$1列的值赋给数组,最后循环打印 [root@localhost131 ~]# who | awk '{ip[$1]++} END{for(i in ip)print i,ip[i]}' root 2