呆呆的行为我不明白

gawk behaviour I don't understand

我正在尝试使用 gawk 4.1.4 计算文件字段 12 中不同值的数量,并计算每个值出现的次数。我有两个简短的程序,它们对第一个问题给出了不同的答案,我不知道为什么。

{if(a[]++==1){count++}} END {print count}

...给出的结果是 435,176,而

{a[]++} END {for (i in a){count++};print count}

...结果为 599,845。

你能解释一下这个行为,并告诉我哪个值是正确的吗?我在Windows(ezwinport)下运行,字段分隔符是tab.

Obviously the 2nd one seems right! You already have the count stored and you don't need a separate variable

您使用 count 来识别唯一事件的方式在这两种情况下都是错误的,因为它是 not 跟踪每个唯一实例。

使用数组本身的值。

推导逻辑count

{if(a[]++==1){count++}} END {print count}

错误的 ,但它所做的事实是 post-increment operator only when a field in </code> 第二次出现,它在 <code>count 变量中被跟踪。因此,您在输出中看到的 lesser 计数。

另一方面,

{a[]++} END {for (i in a){count++};print count}

几乎是正确的,但是您不需要 count 变量,您已经将它作为值的一部分存储在数组 a 中,由唯一值 [=19] 索引=].做上面的也一样

{a[}++; next} END {for (i in a) print a[i]}

一个小例子来演示它,

cat file
1 2 3
1 2 3
1 2 1
1 1 1
2 3 1
3 4 1

假设我担心 </code> 中的唯一实例及其出现次数。做你的第一个例子,</p> <pre><code>awk '{if(a[]++==1){count++}}END {for (i in a) print i,a[i],count}' file 1 1 1 2 3 1 3 1 1 4 1 1

看到最后一列打印的count的错误值,如果你仔细看的话,变量甚至没有跟踪计数per instance但是所有实例的公共变量。

第二种方法,看似 看起来不错,但打印 count4 不清楚哪个实例,假设 multiple 实例及其计数可能会发生。正确的做法是,

awk '{a[]++; next}END {for (i in a) print i,a[i]}' file
1 1
2 3
3 1
4 1

此处 count 而非 a[i] 保存第 2 列中每个唯一值的唯一计数出现次数。

第一个是错误的(逻辑上,不是语法上,谢谢你强调这个事实,@GeorgeVasiliou),因为你需要在==之前++++a[]==1 :

$ awk '{if(++a[]==1){count++}} END {print count}' foo
3

哦对了,我的测试foo:

$ cat foo
1
1
1
2
2
3