AWK语言第二版 1.4 选择

1.4 选择

Awk的样式很适合将输入行中感兴趣的行选取出来,用于后续处理。由于不含动作的样式会将所有匹配该样式的行都打印出来,因此很多Awk程序仅仅就包含一个样式。本节给出一些有用的样式。

通过比较来选择

这个程序使用了一个比较样式,将时薪超过20美元的员工记录选择出来,即把第二个域大等于20的行选择出来:

$2 >= 20

emp.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里面效果一样

你可能感兴趣的:(AWK,linux,开发语言)