如何根据 1 个字段的内容进行 awk 选择?

如何根据 1 个字段的内容进行 awk 选择?

如何选择第二个字段为“2”的所有记录?

我的数据是:

$ cat numbers.txt 
1 2 3 4 5 6 7 8
2 4 6 8 10 12 14 16
3 6 9 12 15 18 21 24

我的 awk 是:

 awk '$2 - /^2$/ {print}' numbers.txt 

但我得到了所有行,而不仅仅是第一行:

1 2 3 4 5 6 7 8
2 4 6 8 10 12 14 16
3 6 9 12 15 18 21 24

答案1

你需要使用匹配运算符~, 不是减法运算符 -:

$ awk '$2 ~ /^2$/' file

或使用相等运算符==@格伦·杰克曼的回答

但是让我们看一下您之前的解决方案,以解释为什么您会得到所有的行。

awk '$2 - /^2$/ {print}' numbers.txt

在这里,对于每一行输入,如果表达式$2 - /^2$/为真,您将打印该行,否则不执行任何操作。因为你得到了所有的行,所以表达式似乎$2 - /^2$/总是被评估为 true。

如何awk评估该表达式?

当您使用减法运算符时,结果类型为数字。$2变量是一个数字,但是/^2$/是一个正则表达式,它的数值是多少?

嗯,从POSIX awk 文档:

当 ERE 标记在除“~”或“!~”运算符右侧或作为下述内置函数参数之一之外的任何上下文中作为表达式出现时,结果表达式的值应为相当于:

$0 ~ /ere/

所以,你的awk程序变成:

awk '$2 - ($0 ~ /^2$/) {print}' numbers.txt

您可以看到,每个输入行都会使用正则表达式进行检查/^2$/。由于您的输入行均不匹配,因此表达式的结果$0 ~ /^2$/将为 0。

根据您的输入,所有第二个字段的值都大于 0(减去 0 使其保持不变),这是awk.所以表达式$2 - /^2$/始终为真,导致awk打印所有行。

答案2

~是模式匹配运算符,而不是-。但如果您要测试相等性,请使用相等运算符==

awk '$2 == 2' numbers.txt

相关内容