一、awk简介及常用用法awk编程语言/数据处理引擎创建者:Aho,Weinberger,Kernighanawk的名字取自三者名字的首字母creators基于模式匹配检查输入文本,逐行处理并输出通常在Shell脚本中使用。获取指定数据单独使用时,可以对文本数据进行统计。awk默认支持扩展的常规命令格式。格式一:前置命令|awk[option]'[condition]{instruction}'格式二:前置命令|awk[option]'[condition]{instruction}'文件常用选择选项-F可以指定分隔符,可以省略(awk默认的分隔符是空格和tab键)option-v赋值一个用户定义的变量。常用的条件可以省略(默认输入显示所有匹配项),可以使用正则表达式限制范围。awk默认支持扩展的正则表达式。awk常用内置变量FS保存或设置字段分隔符,例如FS=":"与-F函数相同RS:RecordSeparator,记录分隔符ORS:OutputRecordSeparate,输出当前记录分隔符(行分隔符)OFS:OutofFieldSeparator,输出字段分隔符,缩写含义解释$n指定分隔的第n个字段,比如$1,$2分别代表正文的第一列,第二列等等$0的全部内容文本的当前行NR文件当前行的行号NF文件当前行的列数(有几列)常用命令print是最常用的编辑命令;如果有多个编辑命令,可以用分号分隔。Case11)awk过滤数据时,支持只打印某一列,如第2列,第5列等。处理文本时,如果不指定分隔符,默认使用空格,制表符等作为分隔符。[root@case100~]#catawk.txtthellotheworldwelcometobeijing[root@case100~]#awk'{print$1,$3}'awk.txt//打印文档的第一列和第三列helloworldwelcomebeijing合并pipelineFiltercommandoutput:[root@case100~]#df-h|awk'{print$4}'//打印磁盘剩余空间2)Option-F可以指定分隔符输出分号分隔的首尾passwd文件中7个字段,显示的字段用逗号分隔,操作如下:[root@bigyong~]#awk-F:'{print$1","$7}'/etc/passwdroot,/bin/bashbin,/sbin/nologindaemon,/sbin/nologinadm,/sbin/nologinlp,/sbin/nologinsync,/bin/sync...3)用awk提取本机网络流量,根分区剩余容量,并获取远程失败的IP地址提取IP地址分步实现的思路和操作如下——通过ifconfigeth0查看网卡信息,包括网卡流量:[root@case100~]#ifconfigeth0eth0flags=4163mtu1500inet192.168.4.100netmask255.255.255.0broadcast192.168.4.255ether52:54:00:af:e6:6atxqueuelen1000(Ether10net)RX7字节数据包5769307(5.5MiB)RXerrors0dropped100380overruns0frame0TXpackets4678bytes736178(718.9KiB)TXerrors0dropped0overruns0carrier0collisions0RX是接收的数据量,TX是发送的数据量packets的单位是数据包的个数,bytes的单位是bytes:[root@case100~]#ifconfigeth0|awk'/RXp/{print$5}'//过滤接收数据的流向5797165[root@case100~]#ifconfigeth0|awk'/TXp/{print$5}'//Filtertheflowofsentdata7610064)逐步提取根分区剩余容量的思路和操作如下——通过df命令查看根分区的使用情况,包括剩余容量:[root@case100~]#df-h/filesystemcapacityusedavailableused%mountpoint/dev/vda120G8.8G12G44%/输出上面结果最后一行第四列:awk中直接使用正则表达式:[root@case100~]#df-h/|awk'/\/$/{print$3}'8.8G5)option-vassigna用户自定义变量[root@case100~]#echo'12345'|awk-vistor=100'{if(istor=100){print$0}}'123456)输出前4个columns[root@case100~]#awk-F:'{NF=4}1'/etc/passwd7)定义输出格式Output:1和4列分隔符是=行分隔符是*(默认是回车)ORS:OutputRecordSeparate,输出当前记录分隔符(Lineseparator)OFS:OutofFieldSeparator,输出字段分隔符,缩写含义解释[root@k8s-node2~]#awk-F:'BEGIN{OFS="=";ORS="*"}{print$1,$4;}'/etc/passwdroot=0*bin=1*daemon=2*adm=4*lp=7*sync=0*shutdown=0*halt=0*mail=12*operator=0*games=100*ftp=50*nobody=99*systemd-bus-proxy=998*systemd-network=192*dbus=81*polkitd=997*tss=59*sshd=74*postfix=89*chrony=995*guanzj=0*zabbix=994*ng#输出分隔符为*[root@k8s-node2~]#awk-F:'BEGIN{OFS="*"}{print$1,$4;}'/etc/passwdroot*0bin*1daemon*2adm*4lp*7sync*0shutdown*02.awk过滤的时机BEGIN{}END{}命令awk过滤的时机awk会逐行处理文本,支持在Dosome处理第一行前的准备工作,处理完最后一行后做一些总结工作。命令格式如下:awk[option]'[condition]{command}'fileawk[option]'BEGIN{command}{command}END{command}'fileBEGIN{}行前处理,读取前执行文件内容,执行一次命令{}逐行处理,边读文件边执行,执行命令n次END{}后处理,读文件后执行,执行一次命令[root@case100~]#awk'BEGIN{A=22;printA}'22[root@case100~]#awk'BEGIN{printx+1}'#x可以不定义,可以直接使用,默认值为01[root@case100~]#awk'BEGIN{print3.2+3.5}'6.7Case21)统计系统中使用bash作为登录shell的用户总数:a.在预处理期间分配变量x=0b。然后逐行读取/etc/passwd文件。如果发现登录shell为/bin/bash,则将x加1。所有处理完成后,输出x的值即可。相关操作及结果如下:[root@case100~]#awk'BEGIN{x=0}/bash$/{x++}END{printx}'/etc/passwd52)格式输出/etc/passwd文件要求:format输出passwd文件内容时,要求第一行为列表标题,中间打印用户名、UID、home目录信息,最后一行提示处理的总行数text,如图1所示。3)按照实现思路编写,在验证awk过滤语句的输出信息时,可以使用“\t”显示制表位:[root@case100~]#awk-F:'BEGIN{print"USER\tUID\tHome"}\>{print$1"\t"$3"\t"$6}\>END{print"Total",NR,"lines."}'/etc/passwdUSERUIDHomeroot0/rootbin1/bindaemon2/sbinadm3/var/admlp4/var/spool/lpdsync5/sbinshutdown6/sbinhalt7/sbinmail8/var/spool/mailoperator11/rootgames12/usr/gamesftp14/var/ftpnobody99/systemd-network192/Case31)使用正则表达式设置条件,在bash中输出完整日志最后:[root@case100~]#awk-F:'/bash$/{print}'/etc/passwdroot:x:0:0:root:/root:/bin/bashnginx:x:1000:1000::/home/nginx:/bin/bash2)包含root的输出行数据:[root@case100~]#awk-F:'/root/'/etc/passwdroot:x:0:0:root:/root:/bin/bashoperator:x:11:0:operator:/root:/sbin/nologin3)输出root或adm账号的用户名和UID信息:[root@case100~]#awk-F:'/^(root|adm)/{print$1,$3}'/etc/passwdroot0adm34)输出的账户名包含root的基本信息(第一列包含root):[root@case100~]#awk-F:'$1~/root/'/etc/passwdroot:x:0:0:root:/root:/bin/bash5)输出不以nologin结尾的登录shell的用户名和登录shell信息(在第7字段做!~反向匹配):[root@case100~]#awk-F:'$7!~/nologin$/{print$1,$3}'/etc/passwdroot0sync5shutdown6halt7nginx1000......三、awkvalue/stringcomparison/logiccomparisonsettingconditionsusingvalue/stringcomparisonsettingconditions比较符号:==(等于)!=(不等于)>(大于)\>=(大于等于)<(小于)<=(小于等于)使用逻辑比较来设置conditions&&logicalAND:期望多个条件为真||逻辑或:只要满足一个条件就满足要求1)输出第3行的用户记录(行号NR等于3):[root@case100~]#awk-F:'NR==3{print}'/etc/passwddaemon:x:2:2:daemon:/sbin:/sbin/nologin2)输出帐号名和帐号UID小于10的UID信息:[root@case100~]#awk-F:'$3<10{print$1,$3}'/etc/passwdroot0bin1daemon2adm3lp4......3)输出账号名称及账号UID大于等于1000的UID信息:[root@case100~]#awk-F:'$3>=1000{print$1,$3}'/etc/passwdnginx1000bigyong1001kaka51002harry10034)输出用户名为“root”的行:[root@case100~]#awk-F:'$1=="root"'/etc/passwdroot:x:0:0:root:/root:/bin/bash5)逻辑测试条件输出账户UID大于10小于20的账户信息:[root@case100~]#awk-F:'$3>10&&$3<20{print$1,$3}'/etc/passwdoperator11games12ftp146)输出帐号UID大于1000或帐号UID小于10的帐号信息:[root@case100~]#awk-F:'$3>100||$3<1000{print$1,$3}'/etc/passwdroot0bin1daemon2......7)数学运算[root@case100~]#awk'BEGIN{x++;printx}'1[root@case100~]#awk'BEGIN{x=10;printx+=20}'30[root@case100~]#awk'BEGIN{print7+3}'10[root@case100~]#awk'BEGIN{print3+4}'7[root@case100~]#awk'BEGIN{print3*4}'12[root@case100~]#awk'BEGIN{print50%3}'2[root@case100~]#awk'BEGIN{print20/3}'6.66667[root@case100~]#seq200|awk'\$1%3==0'//求200以内3的倍数3691215......8)列出UID在1~1000之间的用户详细信息:[root@case100~]#awk-F:'\$3>=1&&$3<=1000'/etc/passwdbin:x:1:1:bin:/bin:/sbin/nologindaemon:x:2:2:daemon:/sbin:/sbin/nologinadm:x:3:4:adm:/var/adm:/sbin/nologinlp:x:4:7:lp:/var/spool/lpd:/sbin/nologinsync:x:5:0:sync:/sbin:/bin/sync......9)输出/etc/hosts映射文件中127或192开头的记录:[root@case100~]#awk'/^(127|192)/'/etc/hosts127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4192.168.4.200nginx01.test.com10)列出7的倍数或100以内包含7的整数:[root@case100~]#seq100|awk'$1%7==0||$1~/7/'71417212728......4案例4:awk综合脚本应用脚本任务要求如下:登录的本地用户Shell列出这些用户的影子密码记录,并根据每一行“用户名-密码记录”保存结果第一步:按照实现思路编写脚本[root@case100~]#catawk-user.sh#!/bin/bashA=$(awk-F:'/bash$/{print$1}'/etc/passwd)fori在$Adogrep$i/etc/shadow|awk-F:'{print$1,"-->",$2}'done第二步:验证和测试脚本[root@case100~]#./getuser-awk.shroot-->$6$SAyc777Q$DgGi7Pnln0or.Ds04oyL6Y.QnVlMgZDRHMKKICJhiUAHBy4lvziPAZoW0MJz81xYonskLozvzhvNa4H59igSl1ng-->!!kaka5-->$6$uyZDpbUl$.CjkBefPZHXrRTcKc1csv7ZbbhHMMD4oQmum9lajJ1ot9at6fmIey5AE4kmUSoaWE/ofmFxyP2Dc6PAcczXdw0harry-->!!