awk生产环境实战案例:
(一):请执行命令取出linux中eth0的IP地址
法1: ifconfig eth0| grep 'inet addr'| awk -F":" '{print $2}'|awk '{print $1}'
法2: ifconfig eth0| grep 'inet addr'| cut -d: -f2|cut -d" " -f1
法3: ifconfig eth0| grep 'inet addr'| cut -d: -f2| awk '{print $1}'
法4: ifconfig eth0| awk -F '[ :]+' 'NR==2 {print $4}'
#法4为最佳实践
我们来说明下这个简单易用的好办法:
提示:本题NR是行号,分隔符+号匹配,[]里一个或多个任意一个分隔符,这里就是匹配一个或多个冒号或空格。
1)awk -F 后面跟分隔符,其中[空格:]多分隔符写法,意思是以空格或冒号做分隔,后面的"+"号是正则表达式,意思是匹配前面空格或冒号,两者之一的1个或1个以上。
2)NR==2和sed -n "2p",相当,意思都是选择第几行,例:
[root@oldboy ~]# ifconfig eth0|awk NR==2 inet addr:10.0.0.185 Bcast:10.0.0.255 Mask:255.255.255.0
3)指定awk -F '[ :]+'分隔符后,不同字符串被分隔的列依次为:
inet | addr | 10.0.0.185 | Bcast:10.0.0.255 Mask:255.255.255.0 | |
第一列 | 第二列 | 第三列 | 第四列 | 后面忽略不计。 |
4)整个答案awk部分意思是,通过NR==2取出第二行,然后,通过-F '[ :]+多分隔符正则匹配,然后通过{print $4}打印出第四列 !
5)掌握了理论要去实践验证才是科学严谨的学习态度,好,来几个例子实践说话吧。
[root@oldboy ~]# echo ---1:----2|awk -F '[-:]+' '{print $2}' 1 [root@oldboy ~]# echo ---1:----2|awk -F '[-:]+' '{print $3}' 2 [root@oldboy ~]# echo ---1:::::2|awk -F '[-:]+' '{print $3}' 2
(二):生产服务器netstat tcp连接状态
法1: netstat -ant|awk '{S[$NF]++}END{for(k in S) print k,S[k]}'
法2: netstat -ant|awk '{S[$6]++}END{for(k in S) print k,S[k]}'
法3: netstat -ant |awk '/^tcp/ {S[$NF]++} END {for(a in S) print a,S[a]}'
法4: netstat -ant |awk '/^tcp/ {S[$6]++} END {for(a in S) print a,S[a]}'
awk庖丁解牛
netstat -n |awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}'
命令拆分 | 功能说明 |
/^tcp/ | 过滤出以tcp开头的行,“^”为正则表达式用法,以...开头,这里是过滤出以tcp开头的行。 |
S[] | 定义了一个名叫S的数组,在awk中,数组下标通常从 1 开始,而不是 0。 |
NF | 当前记录里域个数,默认以空格分隔,如上所示的记录,NF域个数等于6 |
$NF | 表示一行的最后一个域的值,如上所示的记录,$NF也就是$6,表示第6个字段的值,也就是SYN_RECV或TIME_WAIT等。 |
S[$NF] | 表示数组元素的值,如上所示的记录,就是S[TIME_WAIT]状态的连接数 |
++S[$NF] | 表示把某个数加一,如上所示的记录,就是把S[TIME_WAIT]状态的连接数加一 |
END | |
for(key in S) | 遍历S[]数组 |
print key,”\t”,S[key] | 打印数组的键和值,中间用\t制表符分割,显示好一些。 |
小例子测试:
[root@ywxi test]# cat test.txt 001 name wodi 12k 002 name yingsui 15k 003 name jeacen 10k 004 name kuqi 8k 005 name yideng 10k 006 name xiaofan 8k [root@ywxi test]# awk '{S[$NF]++} END {for(a in S) print a,S[a]}' test.txt 15k 1 8k 2 10k 2 12k 1 [root@ywxi test]# awk '{S[$4]++} END {for(a in S) print a,S[a]}' test.txt 15k 1 8k 2 10k 2 12k 1 [root@ywxi test]# awk '{print $4}' test.txt |sort |uniq -c |sort -nr 2 8k 2 10k 1 15k 1 12k
(三):awk数组命令生产实战拓展
假设apache日志内容access.log内容为:
[root@ywxi test]# cat access.log 10.0.0.41 - - [03/Dec/2010:23:27:01 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.42 - - [03/Dec/2010:23:27:01 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.42 - - [03/Dec/2010:23:27:01 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.47 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.42 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 - 10.0.0.47 - - [03/Dec/2010:23:27:02 +0800] "HEAD /checkstatus.jsp HTTP/1.0" 200 -
3.1 统计apache日志单ip访问请求数排名
法1:
[root@ywxi test]# awk '{S[$1]++} END {for(a in S) print S[a],a}' access.log |sort -rn -k2
3 10.0.0.42
2 10.0.0.47
1 10.0.0.41
#提示 $1为第一个域的内容。-k2 为对第二个字段排序,即对数量排序。
法2:
[root@ywxi test]# awk '{print $1}' access.log |sort |uniq -c |sort -rn
法3:
[root@ywxi test]# sed 's/- -.*$//g' access.log |sort |uniq -c |sort -rn
3.2 统计服务器当前单IP连接数最大的IP地址前十
法1: netstat -an |grep EST |awk -F '[ :]+' '{++S[$6]} END {for (key in S) print "ip:"key"----->",S[key]}' |sort -rn -k2 |head
法2: netstat -an |grep EST |awk '{print $5}' |cut -d : -f 1 |grep -v "^$" |awk '{++ETT[$1]} END {for (oldboy in ETT) print "ip:"oldboy "-----",ETT[oldboy] ''}' |sort -rn -k2 |head
(四):处理以下文件内容,将域名取出并根据域名进行计数排序处理:(百度和sohu面试题)
[root@ywxi test]# cat oldboy.log http://www.etiantian.org/index.html http://www.etiantian.org/1.html http://post.etiantian.org/index.html http://mp3.etiantian.org/index.html http://www.etiantian.org/3.html http://post.etiantian.org/2.html
处理结果为:
1 mp3.etiantian.org
2 post.etiantian.org
3 www.etiantian.org
法1: cut -d "/" -f3 test.log |sort |uniq -c
法2: awk -F "/" '{print $3}' test.log |sort |uniq -c
法3: sed 's#^http://##g' test.log|sed 's#/.*##g'|sort |uniq -c
法4: cat test.log |tr "\/" "\n"|grep etiantian|sort|uniq -c
法5: sed -e 's#^.*//\(.*etiantian.*\)/.*html#\1#g' test.log|sort|uniq -c|sort
法6: cut -d "/" -f 3 test.log |awk '{S[$1]++} END {for(a in S) print S[a],a}'
法7: awk -F "/" '{++S[$3]} END {for(key in S) print S[key],key}' test.log
法8: awk -F '[:/]+' '{print $2}' test.log |sort |uniq -c
转载于:https://blog.51cto.com/13707680/2284211