理解AWK阵列与未和不具有不操作者

问题描述:

我有一个文件温度如下:理解AWK阵列与未和不具有不操作者

$ cat temp 
foo 1 
bar 
foo 2 
baz 
bar 

什么这些4个AWK命令之间的差异?

$ awk '!a[$1]++' temp 
foo 1 
bar 
baz 

$ awk '!a[$1]' temp 
foo 1 
bar 
foo 2 
baz 
bar 

$ awk 'a[$1]++' temp 
foo 2 
bar 

$awk 'a[$1]' temp 

为什么上次命令不打印任何东西,为什么最后的命令并不需要打印该行的默认操作?

我也努力理解如何为下面的命令相同

$ awk '{!a[$1]++}END{for(i in a) print a[i]" "i}' temp 
2 foo 
1 baz 
2 bar 


$ awk '{a[$1]++}END{for(i in a) print a[i]" "i}' temp 
2 foo 
1 baz 
2 bar 

在所有情况下的输出,当条件为真时执行的默认操作{ print }

$ awk '!a[$1]++' temp 
foo 1 
bar 
baz 

打印第一列之前没有看到过。后增加意味着!a[$1]在第一次出现后具有正值,因此!a[$1]为假。

$ awk '!a[$1]' temp 
foo 1 
bar 
foo 2 
baz 
bar 

打印时,a[$1]评估为假,它总是会做。

a[$1]值为true,它会在第一时间之后做一旦被递增,即
$ awk 'a[$1]++' temp 
foo 2 
bar 

打印。

$awk 'a[$1]' temp 

打印a[$1]的计算结果为真,它永远不会这样做。

在您的其他示例中,您无条件地在两种情况下递增a[$1]。输出发生在END块中,您可以在其中获得每个已设置密钥的输出。

请记住,awk程序的结构是condition { action },其中默认条件是true并且默认操作是{ print }。当您将!添加到条件时,您会否定它。在你最后的两个例子中,你在动作中应用,并放弃结果,所以行为没有区别。

+0

谢谢汤姆,这很好解释,但在我的另一个例子中,把一个!在[$ 1] ++没有任何区别之前?你的意思是说{!a [$ 1] ++}和{a [$ 1] ++}都是相同的?在awk块 – Vicky

+0

我编辑了我的答案,添加了一些更多的细节,希望能够让事情更加清晰。 –

+0

再次感谢汤姆 – Vicky