写个文件
message.txt
Proto Recv-Q Send-Q Local-Address Foreign-Address State
tcp 0 4166 localhost:80 61.148.242.38:30901 ESTABLISHED
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 localhost:80 111.205.5.146:18222 TIME_WAIT
tcp 0 0 localhost:80 640.101.225:3753822 FIN_WAIT2
tcp 0 0 localhost:80 111.104.224.189:1222 ESTABLISHED
tcp 0 0 localhost:80 111.109.224.111:42209 ESTABLISHED
tcp 0 0 localhost:80 111.204.227.77:11222 FIN_WAIT2
tcp 0 0 localhost:80 111.109.224.111:42229 ESTABLISHED
tcp 0 0 localhost:80 111.60.222.36:36922 TIME_WAIT
tcp 0 4166 localhost:80 611.108.222.38:30221 ESTABLISHED
tcp 0 1 localhost:80 11 0 22 22
tcp 0 1 localhost:80 111.102.221.209:22225 FIN_WAIT1
tcp 0 0 localhost:80 111.104.224.189:4226 ESTABLISHED
tcp 0 0 localhost:80 111.60.222.163:51222 TIME_WAIT
tcp 0 1 localhost:80 211.105.223.92:50221 LAST_ACK
tcp 0 0 localhost:80 111.109.224.111:42240 ESTABLISHED
tcp 0 0 localhost:80 111.106.22.85:50022 FIN_WAIT2
tcp 0 0 :::22 :::* LISTEN
打印第一列和第6列
默认是‘’ 分割 -F 指定分割符
awk '{print $1,$6}' message.txt
Proto State
tcp ESTABLISHED
tcp LISTEN
tcp LISTEN
tcp LISTEN
tcp TIME_WAIT
tcp FIN_WAIT2
tcp ESTABLISHED
tcp ESTABLISHED
tcp FIN_WAIT2
tcp ESTABLISHED
tcp TIME_WAIT
tcp ESTABLISHED
tcp 0
tcp FIN_WAIT1
tcp ESTABLISHED
tcp TIME_WAIT
tcp LAST_ACK
tcp ESTABLISHED
tcp FIN_WAIT2
tcp LISTEN
输出某一列大与某个值
awk ' $3>0 {print $0}' message.txt
或
awk ' $3>0' message.txt
Proto Recv-Q Send-Q Local-Address Foreign-Address State
tcp 0 4166 localhost:80 61.148.242.38:30901 ESTABLISHED
tcp 0 4166 localhost:80 611.108.222.38:30221 ESTABLISHED
tcp 0 1 localhost:80 11 0 22 22
tcp 0 1 localhost:80 111.102.221.209:22225 FIN_WAIT1
输出某一列等于某个值
awk '$3=4166 {print $0}' message.txt
或者
awk '$3=4166' message.txt
Proto Recv-Q 4166 Local-Address Foreign-Address State
tcp 0 4166 localhost:80 61.148.242.38:30901 ESTABLISHED
tcp 0 4166 0.0.0.0:3306 0.0.0.0:* LISTEN
tcp 0 4166 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 4166 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 4166 localhost:80 111.205.5.146:18222 TIME_WAIT
tcp 0 4166 localhost:80 640.101.225:3753822 FIN_WAIT2
tcp 0 4166 localhost:80 111.104.224.189:1222 ESTABLISHED
tcp 0 4166 localhost:80 111.109.224.111:42209 ESTABLISHED
tcp 0 4166 localhost:80 111.204.227.77:11222 FIN_WAIT2
tcp 0 4166 localhost:80 111.109.224.111:42229 ESTABLISHED
tcp 0 4166 localhost:80 111.60.222.36:36922 TIME_WAIT
tcp 0 4166 localhost:80 611.108.222.38:30221 ESTABLISHED
tcp 0 4166 localhost:80 11 0 22 22
tcp 0 4166 localhost:80 111.102.221.209:22225 FIN_WAIT1
tcp 0 4166 localhost:80 111.104.224.189:4226 ESTABLISHED
tcp 0 4166 localhost:80 111.60.222.163:51222 TIME_WAIT
tcp 0 4166 localhost:80 211.105.223.92:50221 LAST_ACK
tcp 0 4166 localhost:80 111.109.224.111:42240 ESTABLISHED
tcp 0 4166 localhost:80 111.106.22.85:50022 FIN_WAIT2
tcp 0 4166 :::22 :::* LISTEN
第三列的值为0 && 第6列的值为LISTEN
awk '$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:* LISTEN
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN
tcp 0 0 127.0.0.1:9000 0.0.0.0:* LISTEN
tcp 0 0 :::22 :::* LISTEN
awk的内建变量
$0 当前记录(这个变量中存放着整个行的内容)
1 1~ 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
1 ##
2 # User Database
3 #
4 # Note that this file is consulted directly only when the system is running
5 # in single-user mode. At other times this information is provided by
6 # Open Directory.
7 #
8 # See the opendirectoryd(8) man page for additional information about
9 # Open Directory.
10 ##
11 nobody /var/empty
7、正则表达式例子:字符串匹配过滤
awk '$6 ~ /FIN/ || NR==1 {print NR,$1,$6}' OFS="\t" message.txt
FIN是要模糊搜索的字符串
1 Proto State
7 tcp FIN_WAIT2
10 tcp FIN_WAIT2
15 tcp FIN_WAIT1
20 tcp FIN_WAIT2
根据某一列的值进行文件拆分
根据第六列的值进行拆分,拆分后每个文件的内容,可以使用cat命令自行进行查看。
awk ‘NR!=1 {print > $6}’ message.txt
-rw-r–r-- 1 zhangsan staff 60B 12 9 14:10 0
-rw-r–r-- 1 zhangsan staff 561B 12 9 14:10 ESTABLISHED
-rw-r–r-- 1 zhangsan staff 78B 12 9 14:10 FIN_WAIT1
-rw-r–r-- 1 zhangsan staff 231B 12 9 14:10 FIN_WAIT2
-rw-r–r-- 1 zhangsan staff 77B 12 9 14:10 LAST_ACK
-rw-r–r-- 1 zhangsan staff 312B 12 9 14:10 LISTEN
-rw-r–r-- 1 zhangsan staff 234B 12 9 14:10 TIME_WAIT
额外例子,重定向到指定的文件名(不按默认的列内容分组输出)
awk ‘NR!=1 {if($6 ~ /ESTABLISHED/) print > “1.txt”; else if($6 ~ /FIN/) print > “2.txt”; else print > “3.txt” }’ message.txt
total 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
[root@sdw5 demo]#
[root@sdw5 demo]#
[root@sdw5 demo]#
[root@sdw5 demo]# awk 'NR!=1 {if($6 ~ /ESTABLISHED/) print > "1.txt"; else if($6 ~ /FIN/) print > "2.txt"; else print > "3.txt" }' message.txt
[root@sdw5 demo]#
[root@sdw5 demo]#
[root@sdw5 demo]# ll
total 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}'
ls -ltr | awk '{sum+=$5} END {print sum}'
907441953
统计进阶:根据第六列,统计每个值出现的次数
awk '{a[$6]++;} END{for (i in a) print i "," a[i];}' message.txt
LISTEN,4
LAST_ACK,1
State,1
FIN_WAIT1,1
FIN_WAIT2,3
TIME_WAIT,3
ESTABLISHED,7
0,1
BEGIN,END,{}总结介绍
END的意思是“处理完所有的行的标识”,即然说到了END就有必要介绍一下BEGIN,这两个关键字意味着执行前和执行后的意思,语法如下:
BEGIN{ 这里面放的是执行前的语句 }
END {这里面放的是处理完所有的行后要执行的语句 }
{这里面放的是处理每一行时要执行的语句}
经典例子赠送
#打印99乘法表
seq 9 | sed ‘H;g’ | awk -v RS=’’ ‘{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")}’
统计访问IP次数并排序取前10
awk '{a[$1]++}END{for(v in a)print v,a[v]|"sort -k2 -nr |head -10"}' access.log
按连接数查看客户端IP
netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr