awk工具

格式1:前置命令 |awk [选项] '[条件]{编辑指令}'
格式2:awk [选项] '[条件]{编辑指令}' 文件名

其中,print是最常用的编辑指令,若有多条编辑指令,可以用分号分隔。
处理文本时,若未指令分隔符,则默认将空格、制表符等作为分隔符。

常用选项:
-F:指定分隔符,可省略(默认空格或Tab位)
-V:调用外度shell变量

例:awk -F: '{print $1 "," $7}' /etc/passwd
输出/etc/passwd文件中以冒号分隔第1、7列,显示不同列之间以逗号隔开。

awk -F [:/] '{print $6 $8}' /etc/passwd
以“:”或“/”分隔文本内容,打印第6列和第8列。

awk过滤的时机
BEGIN{编辑指令} 在行前处理
在读入第一行之前执行

{编辑指令} 逐行处理
每读一行执行一次

END{编辑指令} 行后处理
在读完最后一行后执行

awk [选项] 'BEGIN{编辑指令}{编辑指令}END{编辑指令}' 文件

awk [选项] '[选项]/正则匹配/{编辑指令}' 文件

例:awk -F: '/^[a-d]/{print $2,$4}' /etc/passwd
输出以a-d开头的第2列和第4列

awk '/^a|h$/{print}' a.txt
输出以a开头或h结尾的行

awk '$6~/bin$/{print}' a.txt
输出以第6列做匹配,以bin结尾的

awk '$3!~/nologin$/{print}' a.txt
输出以第3列做匹配,不以nologin结尾的

awk内置变量
FS:保存或设置字段分隔符
$n:指定分隔的第n个字段
$0:当前读入的整行文本内容
NF:记录当前处理行的字段个数(列数)
NR:记录当前已读入行的数量(行数)

数值比较
==等于、!=不等于

大于、>=大于或等于
<小于、<=小于或等于

逻辑比较测试
&&:逻辑与
||:逻辑或

运算符
+、-、、/、%
++、--、+=、-=、
=、/=

例: awk 'NR==3{print}' a.txt
输出第三行

awk 'NR%==1{print}' a.txt
输出奇数行

awk 'NR<=3{print}' a.txt
输出前3行

awk 'NR>=3{print}' a.txt
输出第3行到末尾行

awk '$1=="sy"{print}' a.txt
输出第1列是sy

awk -F: '$1==ENVIRON["USER"]{print $1,$6,$7}' /etc/passwd
输出当前用户的用户名、宿主目录、登录shell信息

awk 'NR>=3&&NR<=5{print}' a.txt
输出第3-5行

awk 'NR==3||NR==5{print}' a.txt
输出第3行和第5行

awk '$7!~/nologin$/||$1~/^[a-d]/{print}' a.txt
匹配第7列输出不以nologin结尾,或在第1列匹配以a-d开头

awk 'BEGIN{X=0}{x++}END{print "值" x}' a.txt
每读一行x自加1,最后打印x的值

awk 'NR%7==0||/NR~/7/{print}' a.txt
输出100以内7的倍数,或包含7的数。

awk流程控制
单分支:
if(条件){编辑指令}
双分支:
if(条件){编辑指令}else{编辑指令}
多分支:
if(条件){编辑指令}else if(条件){编辑指令}else{编辑指令}

例:awk -F: 'BEGIN{i=0;j=0}{if($3<=500){i++}else{j++}}END{print i,j}' /etc/passwd
统计UID小于或等于500,UID大于500的用户分别是多少

while循环
while(条件){编辑指令}
例:awk -F[:/] 'BEGIN{i=1}{while(i<=NF){if($i~/root/){j++};i++}}END{print j}' /etc/passwd
统计"root"的次数

awk数组
定义数组
格式:数组名[下标]=值
调用数组
格式:数组名[下标]
遍历数组
格式:for(变量 in 数组名){print 数组名[变量]}

例:awk '{ip[$1]++}END{for(i in ip){print i,ip[i]}}' a.txt
统计每个IP地址访问服务器的次数