【问题标题】:Awk/Unix group byawk/Unix 分组
【发布时间】:2013-02-17 00:40:31
【问题描述】:

有这个文本文件:

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

试图得到这个(计数):

joe 1
jim 1
bob 2
mike 3

谢谢,

【问题讨论】:

    标签: unix awk


    【解决方案1】:
    $ 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 处理第 1 行之后的行
    • arr[$1]++ 递增数组arr(与, 拆分),第一列为键
    • END{} 块在文件处理结束时执行
    • for (a in arr) 使用 a 键迭代 arr
    • print a print key , arr[a] array with a key

    【讨论】:

    • +1 表示一行 awk 答案(这是问题中的标签)!我喜欢在这里学习...
    • 当文件中第一次出现“bob”在“mike”之前时,为什么“mike”打印在“bob”之前?...
    • 数组在awk中任意排序。因此,不能保证输出顺序。
    • 我现在看到,NR 跳过了第一行,END 之后的所有内容只运行一次。谢谢!
    • 一个小的修改可以让你对年龄求和而不是仅仅计算记录:awk -F, 'NR>1{arr[$1]+=$2}END{for (a in arr) print a, arr[a]}' file.txt'
    【解决方案2】:

    剥离标题行,删除年龄字段,将相同的名称组合在一起(排序),计算相同的运行次数,以所需的格式输出。

    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 以获得快速紧凑的答案!我才完成了一半...你按字母顺序给出(没有被问到...)
    • 我们将看看 OP 想要它如何排序,如果有的话。 (要按计数排序,请在awk 之前添加sort -n)。
    【解决方案3】:

    看起来你想要排序的输出。您可以简单地通过管道或打印到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] }
      

      【讨论】:

      • 喜欢使用 /[0-9]/ 地址以仅适用于其中包含年龄的行...
      【解决方案5】:

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

      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
      

      享受吧!

      【讨论】:

        【解决方案6】:
        cut -d',' -f 1 file.txt |
        sort | uniq -c
        
        2 bob
        1 jim
        1 joe
        3 mike
        

        【讨论】:

          猜你喜欢
          • 2016-07-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-13
          • 2021-02-12
          • 2018-02-16
          相关资源
          最近更新 更多