如何提取 space 分隔的 .txt 文件中的特定列并存储每个唯一值及其出现次数 [Unix - Bash]

How to extract a certain column in a space-delimited .txt file and store each unique value along with the number of times it appears [Unix - Bash]

假定要提取的列包含数值

我不确定实现此目标的最佳策略。

我想先提取列并将值存储在某种数组中。然后遍历它并删除所有不唯一的值,同时跟踪该值的数量并将该数量存储在单独的数组中。那么,每个唯一数字都会有一个数组,而相应的数组会包含原始列中找到的该数字的数量?

到目前为止我所拥有的(从 .txt 中获取第二列并将每一行值存储在数组中(每个索引一个)):

vals=($(awk '{print }' test.txt))

我不确定应该如何存储 每个唯一值及其出现的次数,我想我需要类似于字典的东西?

我知道我可以使用 sort 和 uniq 来删除不唯一的值,但是我不知道如何计算每个值的总出现次数。

将使用的示例 .txt 文件

George 82 56 55
Martin 22 56 21
Cole 22 49 102

awk '{print }' 提取第二个 ,而不是行。

确实可以用sortuniq来实现,这就是Unix传统的'toolbox'方法,之前很多人也想到了:

awk '{print }' file.txt | sort -n | uniq -c

(uniq -c 计算相邻的重复项而不是删除它们。在任何 non-weird Unix 系统上,您可以使用 man {programname} 获取程序文档,并且 man uniq向您展示了几个对各种事情都有用的选项,包括 -c。)

但是awk自己也可以完成(或几乎)全部工作:

awk '{++c[]} END{for(v in c){print c[v],v}}' file.txt

awk 有 'associative' 数组下标或 'keyed' 任何值,而不仅仅是 more-or-less 连续整数;这是 1970 年代对现在通常称为字典的名称。 (并且所有数组元素和除 NR NF OFS 等预定义变量之外的变量都被初始化为空值,在数字上被视为零。)

由于这通常作为 hash-table 实现,传统 awk 中的 for..in 语句可以以任意顺序生成值,标准 (POSIX) 对此进行了编纂。如果您希望它们按数字顺序排列(如 sort|uniq 方法生成的那样),您可以添加 ... | sort -nk2,或者仅在 GNU awk 的 non-ancient 版本上添加(现在普遍但不普遍)你可以使用:

awk '{++c[]} END{PROCINFO["sorted_in"]="@val_num_asc";for(v in c){print c[v],v}}' file.txt