awk中的模式匹配在awk程序命令中非常重要,它决定着被处理数据文件中到底哪一行需要处理,并且做出什么样的处理。
首先,我们先看awk命令的基本语法:awk pattern { actions } 注意:pattern就是指的匹配模式,大括号外加两端空格的是处理动作。
上面awk后面的匹配模式和处理行为至少得有一个,不能两个同时缺失。例如,上篇博文中awk { print } 就表示只做输出到屏幕的处理动作,由于没有匹配模式,那么所有行都需要被输出。
实际上,我们在使用awk的时候,大部分情况都要指定匹配模式,那么设计awk程序中的匹配模式一般有如下6种方式。
1. 关系表达式
awk可以支持许多关系运算符,例如>, <, ==等。对于数据文件,我们经常需要把比较关系作为匹配模式。
#-----------------------------/chapter11/ex11-4.sh------------------ #! /bin/bash #打印第2列的成绩超过80的行 result=`awk '$2 > 80 { print }' scores.txt` echo "$result"
分析:1)使用shell脚本的方式,只不过在程序中用到awk;2)变量result后面加了反引号``,还记得《变量》那篇中讲的单引号、双引号、反引号的区别吗?这边用到了反引号是因为一定要先执行里面的内容;3)反引号中就是awk程序部分,按照了awk pattern { actions } 的形式,不过一定要注意,pattern { actions
}一定要用单引号括起来,防止被理解成shell语言,括起来就会被解释成awk语言了。最后是被处理文件scores.txt;4)$2是awk中的变量,表示被处理数据文件的第2列。
2. 正则表达式
匹配方式和上面一致,不过pattern是基于正则表达式的,一般涉及到数据文件中的字符串匹配。
#-----------------------------/chapter11/ex11-5.sh------------------ #! /bin/bash #输出以字符T开头的行 result=`awk '/^T/ { print }' scores.txt` echo "$result"
#-----------------------------/chapter11/ex11-6.sh------------------ #! /bin/bash #输出以Tom或者Kon开头的行 result=`awk '/^(Tom|Kon)/ { print }' scores.txt` echo "$result"
分析:正则表达式做为匹配模式,一定要把表达式放在两条斜线之间,/regular_expression/。
上面的正则表达式就是选出T开头的或者是Tom或Kon开头的行。
3. 混合模式
混合模式就是把关系表达式和正则表达式结合起来,可以使用&&, ||, !来连接,不过它们都需要在单引号以内。
#-----------------------------/chapter11/ex11-7.sh------------------ #! /bin/bash #混合模式 result=`awk '/^K/ && $2 > 80 { print }' scores.txt` echo "$result"
输出以K开头的行,同时第2列分数大于80分的行。
4. 区间模式
用于匹配一段连续的文本行。语法为:awk ‘pattern1, pattern2 { actions }‘ processed datafile
#-----------------------------/chapter11/ex11-8.sh------------------ #! /bin/bash #区间模式 result=`awk '/^Nancy/, $2==92 { print }' scores.txt` echo "$result"
区间为:以Nancy开头的行为起始,第2列等于92分的行为终止,输出之间的连续的行。注意:当满足patter1或者pattern2的行不只一行的时候,会自动选择第一个符合要求的行。
5. BEGIN模式
一种特殊的内置模式,不需要指定被处理数据文件,直接输出用户设置的内容。在awk中的生命周期只是执行一次。
#-----------------------------/chapter11/ex11-9.sh------------------ #! /bin/awk -f #通过BEGIN模式输出字符串 BEGIN { print "Hello! World." }
6. END模式
和BEGIN模式正好相反,它是在awk处理完所有数据文件之后,即将退出程序时成立,在此之前END模式不成立。BEGIN模式也是如此!
#-----------------------------/chapter11/ex11-11.sh------------------ #! /bin/awk -f #输出报表头 BEGIN { print "scores report" print "=================================" } #输出数据 { print } #报表完成 END { print "================================" print "printing is over" }
参考:Shell从入门到精通