awk是一个强大文本处理工具。

处理流程:处理一行输出一行(将第一行中所有字段赋值给$1 $2 $3...并根据条件来进行后面的动作,重复此过程),在处理庞大文件时不会出现内存溢出或是处理缓慢的问题。

语法:awk [-F|-f|-v] 'BEGIN{} //{command1; command2} END{}' [filename]

选项:

-F 指定分隔符,可以指定多个分隔符使用[:#$]三个分隔符

-f 指定shell脚本

其中语法中:

'' 中是代码块

BEGIN{}初始化代码块,是指定分隔符FS的

// 匹配代码块,可用正则表达式

{} 命令代码块,可用多个命令,常见print

; 多个命令时用分号隔开

END{} 结束代码块,处理完一行后执行的代码块

awk常见变量:

NF:每行有多少字段

NR:目前awk处理的是第几行

FS:目前的分隔符,默认空格为分隔符

$0:每行

$1:每行的第一列

$2:每行的第二列

……

awk逻辑运算符:

<  >   <=  >= ==  != ~匹配  ~!不匹配  && ||

[root@www ~]# cat /etc/passwd | awk 'BEGIN{FS=":"}$3<10{print $0}'
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
[root@www ~]# cat /etc/passwd |awk -F ":" '{if($1~"root"){print $0}}'
root:x:0:0:root:/root:/bin/bash
[root@www ~]# cat /etc/passwd |awk -F ":" '{if($1~"root")print $0}'
root:x:0:0:root:/root:/bin/bash
[root@www ~]# cat /etc/passwd | awk 'BEGIN{FS=":"}$1~"emon"{print $0}'
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[root@www ~]# cat /etc/passwd |awk -F ":" '{if($1~/root/)print $0}'
root:x:0:0:root:/root:/bin/bash
[root@www ~]#

从第二行开始处理文本

[root@www ~]# lastlog | head -5 | awk 'BEGIN{NR>=2}$1~"root"{print $1"\t"$3}' #最好使用{}来print
root    192.168.146.1
[root@www ~]# lastlog | head -5 | awk 'BEGIN{NR>=2}{if($1~"root")print $1"\t"$3}'
root    192.168.146.1
[root@www ~]# lastlog | head -5 | awk 'BEGIN{NR>=2}$1~/root/{print $1"\t"$3}'
root    192.168.146.1
[root@www ~]#

注:if语句一定要在{}中,if的条件必须在()中

应用案列:

统计netstat -anp 状态为LISTEN和CONNECT的连接数量分别是多少
netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i," ",sum[i]}'
统计/home目录下不同用户的普通文件的总数是多少?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i," ",sum[i]}'   
mysql        199 
root           374 
统计/home目录下不同用户的普通文件的大小总size是多少?
ls -l|awk 'NR!=1 && !/^d/{sum[$3]+=$5} END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i," ",sum[i]/1024/1024,"MB"}'

应用案例2:

1.统计access.log下ip及对应个数
root@www:/var/log/nginx# awk '{counts[$1]++}END{for(ip in counts) {print ip,counts[ip]}}' /var/log/nginx/access.log
192.168.146.106 2
192.168.146.107 1
192.168.146.1 18
192.168.146.105 2


2.统计tcp状态名称及对应个数
root@www:~# ss -ant |awk 'NR>1 {tcpco[$1]++}END{for(i in tcpco){print i,tcpco[i]}}'
TIME-WAIT0 12
LISTEN 22
ESTAB 21

root@www:~# netstat -ant |awk 'NR>2 {tcpco[$6]++}END{for(i in tcpco){print i,tcpco[i]}}'
LISTEN 22
ESTABLISHED 21
TIME_WAIT 13
root@www:~#


3.统计passwd以bash名称统计个数
root@www:~# awk -F ':' '{shells[$7]++}END{for(i in shells){print i,shells[i]}}' /etc/passwd
/bin/sync 1
/bin/bash 2
/bin/sh 1
/bin/false 4
/usr/sbin/nologin 27
root@www:~# awk -F ':' '{shells[$NF]++}END{for(i in shells){print i,shells[i]}}' /etc/passwd    #NF是字段数量,总共多少字段,也就是取的最后一个字段了。
/bin/sync 1
/bin/bash 2
/bin/sh 1
/bin/false 4
/usr/sbin/nologin 27
root@www:~#