我有一个命令不断输出几行不同的行(一个流),我想要每行发生的次数的实时摘要(几秒钟的延迟是可以接受的)。
例如,如果我的命令输出以下内容:
apple
apple
apple
apple
banana
orange
banana
我想要这样的东西:
4 apple
2 banana
1 orange
并让输出每隔几秒刷新一次。
我怎样才能实现这个目标? (重新读取整个日志文件将花费太长时间,它必须是实时管道的输出)
答案1
你可以使用 awk:
... | awk '{seen[$0]++} !(NR % 10) {print "======"; for (i in seen) print seen[i], i}'
这将保留重复项的计数 ( seen[$0]++
),并每十个输入行打印它们 ( !(NR % 10)
)。例如:
% % while sleep 1; do echo $((RANDOM % 10)); done | awk '{seen[$0]++} !(NR % 10) {print "======"; for (i in seen) print seen[i], i}'
======
1 0
1 1
3 3
1 6
2 7
2 9
======
3 0
3 1
1 2
3 3
1 4
2 5
2 6
3 7
2 9
======
3 0
3 1
2 2
3 3
2 4
5 5
4 6
3 7
2 8
3 9
...
答案2
可以用一个简短的脚本来完成,perl
例如:
#! /usr/bin/perl
system qw(tput sc); # save cursor
$rc = `tput rc; tput ed`; # restore cursor and erase down
sub report {
print $rc;
print "$_: $c{$_}\n" for sort {
($c{$b} <=> $c{$a}) || ($a cmp $b)
} keys %c;
STDOUT->flush;
alarm 1;
}
$SIG{ALRM} = \&report;
alarm 1;
while (<>) {
chomp;
$c{$_}++;
}
report;
答案3
watch -n <seconds> "sort <file> | uniq -c"
应该是关于你想要的。运行sort | uniq
每个<seconds>
.