如何在看起来像这样的文件上使用awk:
abcd Z
efdg Z
aqbs F
edf F
aasd A
我想提取字母表中每个字母出现在第二列的次数,因此输出应为:
Z 2
F 2
A 1
答案 0 :(得分:4)
尝试:如果您希望输出顺序与Input_file相同,那么以下内容可以帮助您。
awk 'FNR==NR{A[$2]++;next} A[$2]{print $2,A[$2];delete A[$2]}' Input_file Input_file
如果您不打算花2美元,那么以下内容可能对您有所帮助。
awk '{A[$2]++} END{for(i in A){print i,A[i]}}' Input_file
在第一个解决方案中读取Input_file两次并创建一个索引为$ 2的数组A,并且它的值递增。然后当读取第二个Input_file然后打印$ 2及其计数。 在第二个解决方案中创建一个索引为$ 2并递增其值的数组A.然后在结尾部分浏览数组A并打印它的索引和数组A的值。
答案 1 :(得分:1)
我会使用sort | uniq
来实现这个目的,因为这两个工具专门为这类任务而设计:
cat <<END |
abcd Z
efdg Z
aqbs F
edf F
aasd A
END
awk '{print $2}' | sort -r | uniq -c | awk '{printf "%s %d\n", $2, $1}'
将产生完全所需的输出
Z 2
F 2
A 1
此处awk '{print $2}'
用于从文档中获取第二列,其中字段由一个或多个空格字符分隔。如果我们知道列的宽度是固定的,我们可以使用更快的cut
实用程序。
sort -r | uniq -c
正在执行任务的主要算法部分 - 按相反的顺序对字母进行排序,并计算每个字母的出现次数。
awk '{printf "%s %d\n", $2, $1}'
会对uniq -c
输出进行一些重新格式化,以完全匹配所需的格式。
更新: AWK拥有强大的阵列支持,因此只需使用awk就可以完成:
cat <<END |
abcd Z
efdg Z
aqbs F
edf F
aasd A
END
awk '{a[$2]++}
END {n=asorti(a,b,"@ind_str_desc");
for (k=1;k<=n;k++) {printf b[k], a[b[k]]} }'
我们使用由输入流中找到的字母索引的数组a
,并且在每一行上,由相应字母索引的元素会递增。
在END
子句中,我们颠倒索引的顺序并输出数组。