고유 행의 실시간 개수

고유 행의 실시간 개수

여러 다른 라인(스트림)을 지속적으로 출력하는 명령이 있고 각 라인이 발생하는 횟수에 대한 실시간 요약을 원합니다(몇 초의 지연은 허용됨).

예를 들어, 내 명령이 다음을 출력한다면:

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]++)가 유지되고 10개의 입력 줄마다 인쇄됩니다( !(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>.

관련 정보