Bash
uniq 行的實時計數
我有一個命令可以不斷輸出幾條不同的行(一個流),我想要一個實時總結每行發生的次數(可以接受幾秒鐘的延遲)。
例如,如果我的命令輸出以下內容:
apple apple apple apple banana orange banana
我想要類似的東西:
4 apple 2 banana 1 orange
並讓輸出每隔幾秒刷新一次。
我怎樣才能做到這一點?(重新讀取整個日誌文件會花費很長時間,它必須是實時管道的輸出)
你可以使用 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 ...
可以用一個簡短的
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;