使用命令行工具对sorting序列中的重复项进行计数

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

例如,如果cmd1的输出是:

100 100 100 99 99 26 25 24 24 

我需要另一个命令,我可以pipe上述输出,所以,我得到:

 100 3 99 2 26 1 25 1 24 2 

怎么样;

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

uniq -c至less适用于GNU uniq 8.23,并且完全按照你想要的(假设sorting后的input)。

如果订单不重要

 # 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 

在数字上对数字进行反向sorting,然后对重复进行计数,然后交换左侧和右侧的单词。 alignment列。

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

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

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

然后我们可以使用相关数组条目上的++math运算符来计算数组variablesa中的值:

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

我们可以打印结果值:

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

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

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