开启辅助访问 切换到窄版

打印 上一主题 下一主题

awk命令各种实用型小例子快速入门,熟练掌握Linux三剑客

[复制链接]
作者:海林淀粉厂 
版块:
嵌入式操作系统 linux 发布时间:2020-12-12 14:00:37
13970
楼主
跳转到指定楼层
| 只看该作者 回帖奖励 |倒序浏览 |阅读模式
awk在实际的使用过程中,更多的文本类型进行处理,使用好了Linux三大剑客之一的awk,在shell编程、Linux运维等等中如鱼得水,官方链接学习链接如下:

由于是英文版且访问的蜗牛速度,还是通过简单直接的例子来实现快速入门!
message.txt 文件
Proto Recv-Q Send-Q Local-Address Foreign-Address Statetcp 0 4166 localhost:80 61.148.242.38:30901 ESTABLISHEDtcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:80 0.0.0.0:* LISTENtcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTENtcp 0 0 localhost:80 111.205.5.146:18222 TIME_WAITtcp 0 0 localhost:80 640.101.225:3753822 FIN_WAIT2tcp 0 0 localhost:80 111.104.224.189:1222 ESTABLISHEDtcp 0 0 localhost:80 111.109.224.111:42209 ESTABLISHEDtcp 0 0 localhost:80 111.204.227.77:11222 FIN_WAIT2tcp 0 0 localhost:80 111.109.224.111:42229 ESTABLISHEDtcp 0 0 localhost:80 111.60.222.36:36922 TIME_WAITtcp 0 4166 localhost:80 611.108.222.38:30221 ESTABLISHEDtcp 0 1 localhost:80 11 0 22 22tcp 0 1 localhost:80 111.102.221.209:22225 FIN_WAIT1tcp 0 0 localhost:80 111.104.224.189:4226 ESTABLISHEDtcp 0 0 localhost:80 111.60.222.163:51222 TIME_WAITtcp 0 1 localhost:80 211.105.223.92:50221 LAST_ACKtcp 0 0 localhost:80 111.109.224.111:42240 ESTABLISHEDtcp 0 0 localhost:80 111.106.22.85:50022 FIN_WAIT2tcp 0 0 :::22 :::* LISTEN2、输出指定的列tips:
①单引号中的被大括号括着的就是awk的语句,注意,其只能被单引号包含。
②$1..$n表示第几例。注:$0表示整个行,不指定具体的列默认对整个行进行处理。
如下例子输出第一列和第六列的数据
# awk '{print $1,$6}' message.txt Proto Statetcp ESTABLISHEDtcp LISTENtcp LISTENtcp LISTENtcp TIME_WAITtcp FIN_WAIT2tcp ESTABLISHEDtcp ESTABLISHEDtcp FIN_WAIT2tcp ESTABLISHEDtcp TIME_WAITtcp ESTABLISHEDtcp 0tcp FIN_WAIT1tcp ESTABLISHEDtcp TIME_WAITtcp LAST_ACKtcp ESTABLISHEDtcp FIN_WAIT2tcp LISTENawk ' $3>0 {print $0}' message.txt
或者
awk ' $3>0' message.txt
# awk ' $3>0 {print $0}' message.txt Proto Recv-Q Send-Q Local-Address Foreign-Address Statetcp 0 4166 localhost:80 61.148.242.38:30901 ESTABLISHEDtcp 0 4166 localhost:80 611.108.222.38:30221 ESTABLISHEDtcp 0 1 localhost:80 11 0 22 22tcp 0 1 localhost:80 111.102.221.209:22225 FIN_WAIT1tcp 0 1 localhost:80 211.105.223.92:50221 LAST_ACKawk '$3==0 && $6=="LISTEN" {print $0}' message.txt
# awk '$3==0 && $6=="LISTEN" {print $0}' message.txt tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTENtcp 0 0 0.0.0.0:80 0.0.0.0:* LISTENtcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTENtcp 0 0 :::22 :::* LISTEN# $0 当前记录(这个变量中存放着整个行的内容)
$1~$n 当前记录的第n个字段,字段间由FS分隔
FS 输入字段分隔符 默认是空格或Tab
NF 当前记录中的字段个数,就是有多少列
NR 已经读出的记录数,就是行号,从1开始,如果有多个文件话,这个值也是不断累加中。
FNR 当前记录数,与NR不同的是,这个值会是各个文件自己的型号
RS 输入的记录分隔符, 默认为换行符
OFS 输出字段分隔符, 默认也是空格
ORS 输出的记录分隔符,默认为换行符
FILENAME 当前输入文件的名字
其中:
FS指定输入文本每一行的分隔符为冒号:
OFS 指定每一列的值已\t 进行分隔输出
NR代表awk命令读取到的第几行文本
awk 'BEGIN{FS=":"} {print NR,$1,$6}' OFS="\t" /etc/passwd
# awk 'BEGIN{FS=":"} {print NR,$1,$6}' OFS="\t" /etc/passwd 1 root /root2 bin /bin3 daemon /sbin4 adm /var/adm5 lp /var/spool/lpd6 sync /sbin7 shutdown /sbin8 halt /sbin9 mail /var/spool/mail10 operator /root11 games /usr/games12 ftp /var/ftp13 nobody /14 systemd-network /15 dbus /16 polkitd /17 sshd /var/empty/sshd18 postfix /var/spool/postfix19 mysql /var/lib/mysqlawk '$6 ~ /FIN/ || NR==1 {print NR,$1,$6}' OFS="\t" message.txt
# awk '$6 ~ /FIN/ || NR==1 {print NR,$1,$6}' OFS="\t" message.txt 1 Proto State7 tcp FIN_WAIT210 tcp FIN_WAIT215 tcp FIN_WAIT120 tcp FIN_WAIT2根据第六列的值进行拆分,拆分后每个文件的内容,可以使用cat命令自行进行查看。
# lltotal 4-rw-r--r--. 1 root root 1630 Dec 7 16:42 message.txt# # # # # awk 'NR!=1 {print > $6}' message.txt # # # # lltotal 32-rw-r--r--. 1 root root 60 Dec 7 17:14 0-rw-r--r--. 1 root root 561 Dec 7 17:14 ESTABLISHED-rw-r--r--. 1 root root 78 Dec 7 17:14 FIN_WAIT1-rw-r--r--. 1 root root 231 Dec 7 17:14 FIN_WAIT2-rw-r--r--. 1 root root 77 Dec 7 17:14 LAST_ACK-rw-r--r--. 1 root root 312 Dec 7 17:14 LISTEN-rw-r--r--. 1 root root 1630 Dec 7 16:42 message.txt-rw-r--r--. 1 root root 234 Dec 7 17:14 TIME_WAIT# 9、额外例子,重定向到指定的文件名(不按默认的列内容分组输出)awk 'NR!=1 {if($6 ~ /ESTABLISHED/) print > "1.txt"; else if($6 ~ /FIN/) print > "2.txt"; else print > "3.txt" }' message.txt
执行完成后,可以看到多出来了1.txt,2.txt,3.txt三个文件,已根据第六列的内容,正则匹配不同的条件输出到 自定义的文件名的文本中。
这里已经可以看出来有点编程的味道了,大家都是程序猿就不多介绍了,逻辑很简单。
# lltotal 32-rw-r--r--. 1 root root 60 Dec 7 17:14 0-rw-r--r--. 1 root root 561 Dec 7 17:14 ESTABLISHED-rw-r--r--. 1 root root 78 Dec 7 17:14 FIN_WAIT1-rw-r--r--. 1 root root 231 Dec 7 17:14 FIN_WAIT2-rw-r--r--. 1 root root 77 Dec 7 17:14 LAST_ACK-rw-r--r--. 1 root root 312 Dec 7 17:14 LISTEN-rw-r--r--. 1 root root 1630 Dec 7 16:42 message.txt-rw-r--r--. 1 root root 234 Dec 7 17:14 TIME_WAIT# # # # awk 'NR!=1 {if($6 ~ /ESTABLISHED/) print > "1.txt"; else if($6 ~ /FIN/) print > "2.txt"; else print > "3.txt" }' message.txt # # # lltotal 44-rw-r--r--. 1 root root 60 Dec 7 17:14 0-rw-r--r--. 1 root root 561 Dec 7 17:18 1.txt-rw-r--r--. 1 root root 309 Dec 7 17:18 2.txt-rw-r--r--. 1 root root 683 Dec 7 17:18 3.txt-rw-r--r--. 1 root root 561 Dec 7 17:14 ESTABLISHED-rw-r--r--. 1 root root 78 Dec 7 17:14 FIN_WAIT1-rw-r--r--. 1 root root 231 Dec 7 17:14 FIN_WAIT2-rw-r--r--. 1 root root 77 Dec 7 17:14 LAST_ACK-rw-r--r--. 1 root root 312 Dec 7 17:14 LISTEN-rw-r--r--. 1 root root 1630 Dec 7 16:42 message.txt-rw-r--r--. 1 root root 234 Dec 7 17:14 TIME_WAITls -ltr | awk '{sum+=$5} END {print sum}'
# lltotal 44-rw-r--r--. 1 root root 60 Dec 7 17:14 0-rw-r--r--. 1 root root 561 Dec 7 17:18 1.txt-rw-r--r--. 1 root root 309 Dec 7 17:18 2.txt-rw-r--r--. 1 root root 683 Dec 7 17:18 3.txt-rw-r--r--. 1 root root 561 Dec 7 17:14 ESTABLISHED-rw-r--r--. 1 root root 78 Dec 7 17:14 FIN_WAIT1-rw-r--r--. 1 root root 231 Dec 7 17:14 FIN_WAIT2-rw-r--r--. 1 root root 77 Dec 7 17:14 LAST_ACK-rw-r--r--. 1 root root 312 Dec 7 17:14 LISTEN-rw-r--r--. 1 root root 1630 Dec 7 16:42 message.txt-rw-r--r--. 1 root root 234 Dec 7 17:14 TIME_WAIT# # ls -ltr | awk '{sum+=$5} END {print sum}'4736awk '{a++;} END{for (i in a) print i "," a;}' message.txt
前面看来if的逻辑判断语句,这里用到了for循环输出东西,其中利用到了数组,不懂的可以提出来。
# awk '{a++;} END{for (i in a) print i "," a;}' message.txt LAST_ACK,1LISTEN,4State,1ESTABLISHED,7FIN_WAIT1,10,1FIN_WAIT2,3TIME_WAIT,3END的意思是“处理完所有的行的标识”,即然说到了END就有必要介绍一下BEGIN,这两个关键字意味着执行前和执行后的意思,语法如下:

  • BEGIN{ 这里面放的是执行前的语句 }
  • END {这里面放的是处理完所有的行后要执行的语句 }
  • {这里面放的是处理每一行时要执行的语句}
#打印99乘法表seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表