我有一个命令(cmd1),可以通过对日志文件进行grep来过滤出一组数字。这些数字是无序的,因此我使用sort -gr来获得数字的反向排序列表。这个排序列表中可能存在重复项。我需要找到该列表中每个唯一数字的计数。
例如,如果cmd1的输出为:
100
100
100
99
99
26
25
24
24
我需要另一个可以将上述输出作为管道输入的命令,以便我获得以下结果:100 3
99 2
26 1
25 1
24 2
我有一个命令(cmd1),可以通过对日志文件进行grep来过滤出一组数字。这些数字是无序的,因此我使用sort -gr来获得数字的反向排序列表。这个排序列表中可能存在重复项。我需要找到该列表中每个唯一数字的计数。
例如,如果cmd1的输出为:
100
100
100
99
99
26
25
24
24
我需要另一个可以将上述输出作为管道输入的命令,以便我获得以下结果: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\t%s\n",$2,$1)}END{print}'
100 3
99 2
26 1
25 1
24 2
100 3 99 2 26 1 25 1 24 2 2 24
- Mittenchopsecho "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
- Woodyuniq -c
适用于至少版本为GNU uniq 8.23的系统,并且可以完全满足你的需求(假设输入已经排序)。
sort
命令:sort file_name | uniq -c
。 - Mikhail Geyer如果顺序不重要
# 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
将数字按相反顺序进行数值排序,然后计算重复项,接着交换左右单词的位置。最后对齐成列。
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
$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
排序
:for i in $(printf '%s\n' "${!a[@]}" | sort -nr)
do
echo "$i ${a[$i]}"
done
如果您在my_file中存储了输入,您可以执行以下操作:
sort -nr my_file | uniq -c | awk ' { t = $1; $1 = $2; $2 = t; print; } '
$ cat file
100
100
100
99
99
26
25
24
24
1
ruby -e '
cnt=Hash.new(0)
$<.each{|x| cnt[x.to_i]+=1}
w1,w2=cnt.max_by{|e| e.to_s.length}.map{|e| e.to_s.length+2}
cnt.sort_by{|k,v| [-v,-k]}.each{|k,v|
puts "#{k.to_s.rjust(w1," ")}\t#{v.to_s.rjust(w2," ")}"
}' file
输出:
100 3
99 2
24 2
26 1
25 1
1 1