awk '/pattern/ { actions }' filename
你一般会发现脚本中的模式(/pattern/)是一个正则表达式,此外,你也能够在这里用特殊模式 BEGIN 和 END。所以,咱们也能按照下面的形式编写一条 awk 命令:mysql
awk 'BEGIN { actions } /pattern/ { actions } /pattern/ { actions }...END { actions }' filenames
语法结构以下图:
其中:BEGIN END是AWK的关键字部,所以必须大写;这两个部分开始块和结束块是可选的正则表达式
特殊模块:
BEGIN语句设置计数和打印头部信息,在任何动做以前进行
END 语句输出统计结果,在完成动做以后执行sql
awk经过Pattern(模式)来控制是否处理当前记录,若是当前记录和Pattern匹配,则执行Action(操做)。在awk中,有下列几种模式:数组
一、正则表达式 二、关系表达式 三、组合的Pattern 四、Pattern1,Pattern2 五、BEGIN 六、END
为了说明以上各类模式,咱们这里准备一个文件score.txt,以实例的方式一一进行说明,score.txt文件内容以下:ide
[root@ecs-c13b awk]# cat score.txt guojing 85 92 78 zhaoyun 89 90 75 sanfeng 84 88 80 guanyu 83 78 90 liubei 86 88 79
[root@ecs-c13b awk]# awk '/9[0-9]/ {print $0}' score.txt guojing 85 92 78 zhaoyun 89 90 75 guanyu 83 78 90
以上指令查询有一门课成绩在[90-99]区间的学生的成绩信息,/9[0-9]/部分即为awk程序指令中的Pattern,这里Pattern的类型为正则表达式。学习
awk '$3 ~ /9[0-9]/ {print $0}' score.txt zhaosan 85 92 78 lisheng 89 90 75
这条指令在上一条指令的基础上增长了限制,须要第二门课(数学)成绩在[90-99]区间才可与模式匹配。这里的 ~ 操做符用来表示变量是否与正则表达式匹配,若是要判断不匹配,可使用 !~ 操做符。测试
awk '$3 >= 90 {print $0}' score.txt zhaosan 85 92 78 lisheng 89 90 75
可用来造成模式关系运算符包括: <(小于)、>(大于)、<=(小于或等于)、>=(大于或等于)、= =(等于)和 ! =(不等于)。ui
这条指令的做用也是查询数学成绩在90分以上的学生成绩信息,不过比正则表达式中的范围要大一点,这里100分也是符合模式的。命令行
awk '$3 >= 90 && $3 < 100 {print $0}' score.txt zhaosan 85 92 78 lisheng 89 90 75
布尔运算符 ||(或)&&(和)以及 !(不)将模式组合,组合后若是求值为真则模式匹配,不然不匹配。这里就解决了关系表达式示例中包含了100的问题。excel
awk 'FNR == 2 , FNR == 4 {print $0}' score.txt lisheng 89 90 75 zhaoyun 84 88 80 guanyu 83 78 90
其实这个也能够归为组合的模式中,只是这种模式比较特殊,故单独列出。以,(逗号)隔开的两个Pattern指定一个范围,对从匹配第一个Pattern的记录开始,到匹配第二个Pattern结束的全部记录执行Action
BEGIN模块在awk读取文件以前就执行,通常用来定义咱们的内置变量(预约义变量,eg:FS,RS)能够输出表头(excel表格名称)
BEGIN模式以前在实例中提到,自定义变量,给内容变量赋值等,都是使用过。须要注意的是BEGIN模式后面要结合一个action操做块,包含在大括号内。
awk必须在对输入文件进行任何处理前先执行BEGIN定义的action操做块。咱们能够不要任何输入文件,就能够对BEGIN模块进行测试,由于awk须要先执行完BEGIN模式,才对输入文件作处理。BEGIN模式经常被用来修改内置变量ORS,RS,FS,OFS,等的值。
假如咱们要将学生成绩表打印出来,那总得加点表头什么的吧,就能够放到BEGIN中了。
awk 'BEGIN { print "Print student score table"} {print $0}' score.txt Print student score table zhaosan 85 92 78 lisheng 89 90 75 zhaoyun 84 88 80 guanyu 83 78 90 liubei 86 88 79
ifconfig eth0|awk -F '(addr:)|(Bcast:)' 'NR==2{print $2}'ifconfig eth0|awk -F '[: ]+' 'NR==2{print $4}'ifconfig eth0|awk -F '[^0-9.]+' 'NR==2{print $2}'
也能够写成
ifconfig eth0|awk 'BEGIN{FS="(addr:)|(Bcast:)"} NR==2{print $2}'ifconfig eth0|awk 'BEGIN{FS="[^0-9.]+"} NR==2{print $2}'ifconfig eth0|awk 'BEGIN{FS="[: ]+"} NR==2{print $4}'
注意:命令行 -F 本质就是修改FS的变量。
END 在awk读取完全部的文件的时候,再执行END模块,通常用来输出一个结果(累加,数组的结果)也能够是和BEGIN模块相似的结尾标识信息。
awk 'END { print "Work done"} {print $0}' score.txt zhaosan 85 92 78 lisheng 89 90 75 zhaoyun 84 88 80 guanyu 83 78 90 liubei 86 88 79 Work done
统计数量: grep -c 或 awk
[root@mysql-master ~]# awk '/^$/{print $0}' /etc/services |wc -l16[root@mysql-master ~]# grep -c '^$' /etc/services16[root@mysql-master ~]# awk '/^$/{i++}END{print i}' /etc/services16[root@mysql-master ~]# awk '/^$/{i=i+1}END{print i}' /etc/services16
awk -F: 'BEGIN { print "用户名 UID"} END { print "the over"} $3>500{print $1,$3}' /etc/passwd
补充:awk中变量使用
直接定义,直接使用便可。
awk中字母会被认为是变量,若是真的要给一个变量赋值使用双引号
[root@mysql-master ~]# awk 'BEGIN{ a=123asdf;print a}' #awk中字母会被认为是变量123[root@mysql-master ~]# awk 'BEGIN{ a="123asdf";print a}' #awk中给变量赋值要加双引号;使用变量直接使用便可123asdf