89

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

例如,如果 cmd1 的输出是:

100 
100 
100 
99 
99 
26 
25 
24 
24

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

100     3
99      2
26      1
25      1
24      2
4

5 回答 5

108

怎么样;

$ 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
于 2009-07-07T13:54:57.630 回答
59

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

于 2016-02-29T08:47:19.017 回答
10

如果顺序不重要

# 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
于 2009-07-07T13:44:03.477 回答
10

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

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
于 2017-10-17T10:25:13.707 回答
2

在 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
于 2017-10-17T14:23:22.797 回答