【问题标题】:counting duplicates in a sorted sequence using command line tools使用命令行工具按排序顺序计算重复项
【发布时间】:2010-11-08 17:01:13
【问题描述】:

我有一个命令 (cmd1),它通过 grep 搜索日志文件以过滤出一组数字。数字是 以随机顺序,所以我使用 sort -gr 来获得一个反向排序的数字列表。内可能有重复 这个排序列表。我需要找到该列表中每个唯一数字的计数。

例如如果 cmd1 的输出是:

100 
100 
100 
99 
99 
26 
25 
24 
24

我需要另一个命令,我可以将上述输出通过管道传输到,这样,我得到:

100     3
99      2
26      1
25      1
24      2

【问题讨论】:

标签: bash command-line sorting count duplicates


【解决方案1】:

对数字进行倒数排序,然后计算重复项,然后交换左右单词。对齐到列。

printf '%d\n' 100 99 26 25 100 24 100 24 99 \
   | sort -nr | uniq -c | awk '{printf "%-8s%s\n", $2, $1}'
100     3
99      2
26      1
25      1
24      2

【讨论】:

    【解决方案2】:

    怎么样;

    $ echo "100 100 100 99 99 26 25 24 24" \
        | tr " " "\n" \
        | sort \
        | uniq -c \
        | sort -k2nr \
        | awk '{printf("%s\t%s\n",$2,$1)}END{print}'
    

    结果是:

    100 3
    99  2
    26  1
    25  1
    24  2
    

    【讨论】:

    • 我运行了这个,它在最后生成了一个额外的 $1,$2 打印语句:100 3 99 2 26 1 25 1 24 2 2 24
    • 以下在结果之间添加一个新行并删除末尾的多余行:echo "100 100 100 99 99 26 25 24 24" | tr " " "\n" | sort | uniq -c | sort -k2nr | awk '{printf("%s\t%s\n",$2,$1)}END{print}' | head -n -1 所以你得到:100 3 99 2 26 1 25 1 24 2
    • 语法注意事项,你可以用竖线结束一行,而不是使用反斜杠。
    【解决方案3】:

    在 Bash 中,我们可以使用 关联数组 来计算每个输入值的实例。假设我们有命令$cmd1,例如

    #!/bin/bash
    
    cmd1='printf %d\n 100 99 26 25 100 24 100 24 99'
    

    然后我们可以在相关数组条目上使用++ 数学运算符计算数组变量a 中的值:

    while read i
    do
        ((++a["$i"]))
    done < <($cmd1)
    

    我们可以打印结果值:

    for i in "${!a[@]}"
    do
        echo "$i ${a[$i]}"
    done
    

    如果输出顺序很重要,我们可能需要一个外部的sort 键:

    for i in $(printf '%s\n' "${!a[@]}" | sort -nr)
    do
        echo "$i ${a[$i]}"
    done
    

    【讨论】:

      【解决方案4】:

      uniq -c 至少适用于 GNU uniq 8.23,并且完全符合您的要求(假设输入已排序)。

      【讨论】:

      • 如果输入没有排序,那么只需添加sort命令:sort file_name | uniq -c
      • 太棒了。也适用于 Mac OS X!在 Mojave 10.14.6 上测试。
      【解决方案5】:

      如果顺序不重要

      # echo "100 100 100 99 99 26 25 24 24" | awk '{for(i=1;i<=NF;i++)a[$i]++}END{for(o in a) printf "%s %s ",o,a[o]}'
      26 1 100 3 99 2 24 2 25 1
      

      【讨论】:

      • +1 用于减少 3 个管道。如果你能详细说明它是如何工作的,那就太棒了,这让我感到困惑。 ;-) 谢谢。
      猜你喜欢
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-09
      相关资源
      最近更新 更多