awk,根据表格数据计算计数

awk, calculate count from tabular data

我有一些表格数据,其中第一个字段是唯一 ID,第二个字段是观察值,例如:

1   2
2   2
3   5
4   3
5   2
6   2

如何使用awk计算第二个字段的频率。在获取(观察计数)的示例中:

2   4
3   1
5   1

我不知道之前发生了哪些观察(即示例中没有出现 0、1 和 4)。我虽然需要制作一个关联数组,其中可以添加条目并且在发现观察结果时将值增加 1,但我真的(老实说)不知道该怎么做?

$ awk '{cnt[]++} END{for (i in cnt) print i, cnt[i]}' file
2 4
3 1
5 1

由于 in 运算符,上面的输出顺序实际上是随机的。如果您想控制它,那么使用 GNU awk,您只需在进入循环之前设置顺序(参见 https://www.gnu.org/software/gawk/manual/gawk.html#Controlling-Scanning)。例如:

数组索引从小到大排序(巧合的是和上面顺序一样):

$ awk '{cnt[]++} END{PROCINFO["sorted_in"]="@ind_num_asc"; for (i in cnt) print i, cnt[i]}' file
2 4
3 1
5 1

要按数组值的数字升序排序:

$ awk '{cnt[]++} END{PROCINFO["sorted_in"]="@val_num_asc"; for (i in cnt) print i, cnt[i]}' file
3 1
5 1
2 4

请尝试以下操作:

cat file.txt | awk '{
    dict[]++;
}
END {
    for (key in dict) { print key, dict[key] }
}'

使用 perl 可以更容易地将键按您提供的顺序排序:

$ perl -lane '$seen{$F[1]}++; END{ for (sort keys %seen){ print "$_ $seen{$_}"}}' file
2 4
3 1
5 1

或者如果你想按频率排序:

$ perl -lane '$seen{$F[1]}++; END{ for (sort {$seen{$a} <=> $seen{$b}} keys %seen){ print "$_ $seen{$_}"}}' file
3 1
5 1
2 4

(反转 $a$b 如果你想要降频与升频...)