Awk/Unix 按组分组

47

有一个文本文件:

name, age
joe,42
jim,20
bob,15
mike,24
mike,15
mike,54
bob,21

尝试获取这个(count):
joe 1
jim 1
bob 2
mike 3

谢谢。
6个回答

114
$ awk -F, 'NR>1{arr[$1]++}END{for (a in arr) print a, arr[a]}' file.txt
joe 1
jim 1
mike 3
bob 2

解释

  • -F,:按逗号,分割字段
  • NR>1:处理第二行及以后的行
  • arr[$1]++:将以逗号,分割的每行第一列作为键,增加数组arr的值
  • END{}:该代码块在文件处理完毕时执行
  • for (a in arr):循环遍历数组arr中每个键a
  • print a:输出键a和对应的值arr[a]

6
+1 表示对一行 awk 答案的赞同(这是问题中的标签)!我喜欢在这里学习... - Floris
为什么第一次出现的"bob"在文件中在"mike"之前,但是输出却先显示了"mike"?你有任何评论吗? - Floris
awk 中,数组是任意排序的。因此,输出顺序不能保证。 - nneonneo
1
我现在明白了,NR跳过第一行,END之后的所有内容只运行一次。谢谢! - C B
2
一项小修改就可以让你对年龄进行求和,而不仅仅是计算记录数:awk -F, 'NR>1{arr[$1]+=$2}END{for (a in arr) print a, arr[a]}' file.txt' - Dave

30
去除表头,删除年龄字段,将相同名称的行分组(排序),计算相同的运动次数,按照所需格式输出结果。
tail -n +2 txt.txt | cut -d',' -f 1 | sort | uniq -c | awk '{ print $2, $1 }'

输出

bob 2
jim 1
joe 1
mike 3

+1 为了快速和紧凑的答案!我才刚开始……而你却按字母顺序给出了它(并没有要求这样做……) - Floris
我们将看看 OP 想要如何排序,如果需要的话。 (要按计数排序,请在“awk”之前添加“sort -n”)。 - nneonneo

10

看起来你想要排序后的输出。你可以直接使用管道或打印到 sort -nk 2

awk -F, 'NR>1 { a[$1]++ } END { for (i in a) print i, a[i] | "sort -nk 2" }' file

结果:

jim 1
joe 1
bob 2
mike 3

然而,如果您已经安装了GNU awk,则可以在不使用coreutils的情况下执行排序。以下是将数组按其值排序的单进程解决方案。该解决方案仍应该非常快。运行如下所示:
awk -f script.awk file

script.awk 的内容:

BEGIN {
    FS=","
}

NR>1 {
    a[$1]++
}

END {
    for (i in a) {
        b[a[i],i] = i
    }

    n = asorti(b)

    for (i=1;i<=n;i++) {
        split (b[i], c, SUBSEP)
        d[++x] = c[2]
    }

    for (j=1;j<=n;j++) {
        print d[j], a[d[j]]
    }
}

结果:

jim 1
joe 1
bob 2
mike 3

另一种选择是使用一个简单的命令:

awk -F, 'NR>1 { a[$1]++ } END { for (i in a) b[a[i],i] = i; n = asorti(b); for (i=1;i<=n;i++) { split (b[i], c, SUBSEP); d[++x] = c[2] } for (j=1;j<=n;j++) print d[j], a[d[j]] }' file

4
一个严格的 awk 解决方案...
BEGIN { FS = "," }
{ ++x[$1] }
END { for(i in x) print i, x[i] }

如果文件中真的有name, age,那么您可以修改awk程序来忽略它...
BEGIN   { FS = "," }
/[0-9]/ { ++x[$1] }
END     { for(i in x) print i, x[i] }

1
喜欢使用 /[0-9]/ 地址只处理包含年龄信息的行... - Floris

0

根据这里的答案,我想出了两个函数:

topcpu() {
    top -b -n1                                                                                  \
        | tail -n +8                                                                            \
        | awk '{ print $12, $9, $10 }'                                                          \
        | awk '{ CPU[$1] += $2; MEM[$1] += $3 } END { for (k in CPU) print k, CPU[k], MEM[k] }' \
        | sort -k3 -n                                                                           \
        | tail -n 10                                                                            \
        | column -t                                                                             \
        | tac
}

topmem() {
    top -b -n1                                                                                  \
        | tail -n +8                                                                            \
        | awk '{ print $12, $9, $10 }'                                                          \
        | awk '{ CPU[$1] += $2; MEM[$1] += $3 } END { for (k in CPU) print k, CPU[k], MEM[k] }' \
        | sort -k2 -n                                                                           \
        | tail -n 10                                                                            \
        | column -t                                                                             \
        | tac
}

$ topcpu
chrome           0    75.6
gnome-shell      6.2  7
mysqld           0    4.2
zsh              0    2.2
deluge-gtk       0    2.1
Xorg             0    1.6
scrcpy           0    1.6
gnome-session-b  0    0.8
systemd-journal  0    0.7
ibus-x11         6.2  0.7

$ topmem
top              12.5  0
Xorg             6.2   1.6
ibus-x11         6.2   0.7
gnome-shell      6.2   7
chrome           6.2   74.6
adb              6.2   0.1
zsh              0     2.2
xdg-permission-  0     0.2
xdg-document-po  0     0.1
xdg-desktop-por  0     0.4

享受!


0
cut -d',' -f 1 file.txt |
sort | uniq -c

2 bob
1 jim
1 joe
3 mike

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接