使用awk提取数据并计数

时间:2017-04-16 04:38:44

标签: linux unix awk

如何在看起来像这样的文件上使用awk:

abcd Z
efdg Z
aqbs F
edf  F
aasd A

我想提取字母表中每个字母出现在第二列的次数,因此输出应为:

Z 2
F 2
A 1

2 个答案:

答案 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子句中,我们颠倒索引的顺序并输出数组。