1.4 选择
Awk的样式很适合将输入行中感兴趣的行选取出来,用于后续处理。由于不含动作的样式会将所有匹配该样式的行都打印出来,因此很多Awk程序仅仅就包含一个样式。本节给出一些有用的样式。
通过比较来选择
这个程序使用了一个比较样式,将时薪超过20美元的员工记录选择出来,即把第二个域大等于20的行选择出来:
$2 >= 20emp.data作为输入,输出是:
Beth    21      0
Mark    25      20
Mary    22.50   22通过计算来选择
$2 * $3 > 200 { printf("$%.2f for %s\n", $2 * $3, $1) }这个程序将收入超过200的员工收入及其姓名打印出来
$500.00 for Mark
$495.00 for Mary
$306.00 for Susie通过文本来选择
除了上面的数字测试之外,还能选择包含特定单词或短语的行。下面的程序打印第一个域为 Susie 的行:
$1 == "Susie"其中的操作符连等号 == 用于测试是否相等。你也能用正则表达式(regular expressions)作为样式来进行文本匹配。下面的程序会打印出所有包含 Susie (不管Susie在行的哪个位置)的行:
/Susie/输出结果是
Susie   17      18正则表达式可用于非常非常复杂的文本匹配,附录A.1.4有完整的说明。
样式的组合
多个样式可以使用括号以及逻辑运算符 && 、|| 、 ! (分别代表于、或、非)组合起来。如下程序
$2 >= 20 || $3 >= 20将 $2 最少为 20 或者 $3 最少为20的行打印出来,两个条件都符合的行也只会打一次:
Beth    21      0
Mark    25      20
Mary    22.50   22可以对比下面这个程序,包含两个样式:
$2 >= 20
$3 >= 20其中两个条件都符合的行,会打印两次。
Beth    21      0
Mark    25      20
Mark    25      20
Mary    22.50   22
Mary    22.50   22另外,下面这个程序
!($2 < 20 && $3 < 20)与前面第一个程序的逻辑是一样的,不过可读性会差。
数据校验
现实的数据总是包含错误。数据校验指的是:检查数据格式是否正确,取值是否合理。Awk就是用来做数据校验的极佳工具。
数据校验基本上是反着来的:它不是把包含所需属性的行打印出来,而是打印其中可疑的行。下面的程序使用比较样式,对emp.data每行进行五个合理性测试:
NF != 3   { print $0, "number of fields is not equal to 3" }
$2 < 15   { print $0, "rate is too low" }
$2 > 25   { print $0, "rate exceeds $25 per hour" }
$3 < 0    { print $0, "negative hours worked" }
$3 > 60   { print $0, "too many hours worked" }如果没有错误,就没有输出。(符合Unix哲学)
BEGIN 和 END
还有两个特殊的样式。BEGIN 样式匹配第一个输入文件的第一个行被读入之前,而 END 样式匹配最后一个文件的最后一行处理完之后。下面这个使用 BEGIN 来打印一个表头;为了排版好看,其中的空格数量是经过计算的:
BEGIN { print "NAME    RATE    HOURS"; print "" }
{ print }输出为:
NAME    RATE    HOURS
Beth    21      0
Dan     19      0
Kathy   15.50   10
Mark    25      20
Mary    22.50   22
Susie   17      18可以将多个语句放在同一行内,使用分号隔开。注意 print "" 会打印一个空行,这与单单一个 print 差别很大,后者是打印当前输入行。(不过看起来放在BEGIN里面效果一样)










