uniq 行的实时计数

uniq 行的实时计数

我有一个命令不断输出几行不同的行(一个流),我想要每行发生的次数的实时摘要(几秒钟的延迟是可以接受的)。

例如,如果我的命令输出以下内容:

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>.

相关内容