awk脚本结构
awk 'BEGIN{ statements } statements2 END{ statements }'
ps: statements2默认执行{ print }, 例如打印4到6行的内容:seq 10 | awk 'NR==4,NR==6 { print }' <=> seq 10 | awk 'NR==4,NR==6 '
只打印第4和第6行内容(用分号): seq 10 | awk 'NR==4 ; NR==6'
工作方式
1.执行begin中语句块;
2.从文件或stdin中读入一行,然后执行statements2,重复这个过程,直到文件全部被读取完毕;
3.执行end语句块;
BEGIN{这里放的是执行前的语句}
{这里放的是处理每一行时要执行的语句}
END{这里面放的是处理完所有的行后要执行的语句}
print 打印当前行
使用不带参数的print时,会打印当前行;
echo -e "line1\nline2" | awk 'BEGIN{print "start"} {print } END{ print "End" }'
print 以逗号分割时,参数以空格定界;
echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; \
print var1, var2 , var3; }'
$]] > v1 V2 v3
使用-拼接符的方式(”"作为拼接符);
echo | awk ' {var1 = "v1" ; var2 = "V2"; var3="v3"; \
print var1"-"var2"-"var3; }'
$> v1-V2-v3
内建变量: NR NF $0 $1 $2
NR:表示记录数量,在执行过程中对应当前行号;
NF:表示字段数量,在执行过程总对应当前行的字段数;
$0:这个变量包含执行过程中当前行的文本内容;
$1:第一个字段的文本内容;
$2:第二个字段的文本内容;
echo -e "line1 f2 f3\n line2 \n line 3" | awk '{print NR":"$0"-"$1"-"$2}'
打印每一行的第二和第三个字段:
awk '{print $2, $3}' file
统计文件的行数:
awk ' END {print NR}' file
累加每一行的第一个字段:
echo -e "1\n 2\n 3\n 4\n" | awk 'BEGIN{num = 0 ;
print "begin";} {sum += $1;} END {print "=="; print sum }'
用样式对awk处理的行进行过滤
awk 'NR < 5′ #打印行号小于5的行
awk '$3<5’ #打印第三个字段小于5的行
awk 'NR==1 {print $2}' #打印第一行的第二个字段
awk 'NR==1;NR==4 {print}' file <==> awk 'NR==1;NR==4 ' file #行号等于1和4的打印出来
awk 'NR==1,NR==4 {print}' file <==> awk 'NR==1,NR==4 ' file #打印1到4行
awk '$3==3;$3==5' file awk '$3==3,$3==5' file #跟上面的NR一样
awk '/linux/' #包含linux文本的行(可以用正则表达式来指定,超级强大)
PS:例如打印出机器的内存,free -m | awk '/Mem:/{ print $2 }'
awk '!/linux/' #不包含linux文本的行
个人对awk 'NR…$3...FS= ":" ' 的用法,只对 NR NF FS $1 这些内建变量使用
设置定界符
使用-F来设置定界符(默认为空格)
awk -F ':' '{print $NF}' /etc/passwd <==> awk 'FS= ":" {print $NF}' /etc/passwd <==>awk ' BEGIN{FS=":"} {print $NF}' /etc/passwd
ps: $NF 代表每一行最后的字段 , $(NF-1) 倒数第二个字段
统计
计算所有 .sh文件的大小总和
ls -l .sh* | awk '{sum+=$5} END{print sum}'
运算符:
awk 提供了完整的比较运算符集合,包括 "=="、"<"、">"、"<="、">=" 和 "!="。另外,awk 还提供了 "~" 和 "!~" 运算符,它们分别表示“匹配”和“不匹配”。它们的用法是在运算符左边指定变量,在右边指定规则表达式。如果某一行的第五个字段包含字符序列 root,那么以下示例将只打印这一行中的第三个字段:
$5 ~ /root/ { print $3 }
再例如:
[root@vagrant-centos64 ~]# md5sum -c c 2> /dev/null
a.txt: FAILED
a.txt: FAILED
b.txt: OK
d.txt: OK
只打印为第二字段是”OK”的字段:
[root@vagrant-centos64 ~]# md5sum -c c 2> /dev/null | awk '$2 ~ /OK/'
b.txt: OK
d.txt: OK