행에서 한 번 반복되는 행만 표시하고 해당 행이 몇 번 반복되었는지 나타내는 숫자를 표시하도록 로그 파일을 정리하려면 어떻게 해야 합니까?

행에서 한 번 반복되는 행만 표시하고 해당 행이 몇 번 반복되었는지 나타내는 숫자를 표시하도록 로그 파일을 정리하려면 어떻게 해야 합니까?

현재 로그:

18:56:54 Info: Starting
18:56:55 Error: timed out
18:56:56 Error: timed out
18:56:57 Error: timed out
18:56:58 Info: reconnected
18:56:59 Error: timed out

원하는 출력:

18:56:54 Info: Starting
18:56:55 Error: timed out (3)
18:56:57 Info: reconnected
18:56:58 Error: timed out

내 로그 파일에는 수천 개의 중복 행이 있을 수 있으며 bash/linux 명령을 사용하여 Chrome 로그의 동작을 복제하고 싶습니다.

나는 이것을 꽤 가까운 것으로 찾았습니다. 부분적으로 중복된 연속 행을 제거하되 첫 번째 행과 마지막 행은 유지합니다.

이 마법의 awk 명령을 제공합니다.

awk '{n=$2$3$4$5$6$7}l1!=n{if(p)print l0; print; p=0}l1==n{p=1}{l0=$0; l1=n}END{print}' file

(중요하게 n=$1을 제외하면 타임스탬프가 다를 수 있으며 이는 필수입니다. 압축된 행의 정확한 타임스탬프는 중요하지 않은 것으로 표시됩니다.)

하지만 카운터도 추가해야 제거된 내용을 정확히 알 수 있으므로 가독성과 정확성 사이에서 올바른 절충안을 찾을 수 있습니다. 손실되는 유일한 정보는 중복 메시지에 첫 번째 또는 마지막 타임스탬프가 있는 정확한 시간뿐입니다.

감사합니다. 저는 awk에 능숙하지 않고 방금 uniq에 대해 배웠습니다. 누군가가 저를 솔루션에 연결해 주거나 이것을 재미있는 연습으로 볼 수 있기를 바랍니다. 건배.

답변1

필요없습니다 awk. 그냥 직접 사용하세요 uniq.

uniq -c -f 1 file

-c옵션은 입력에서 행이 연속적으로 발견된 횟수를 제공하며 첫 번째 공백 또는 탭 건너뛰기를 사용하여 필드의 타임스탬프를 구분할 수 있습니다 -f 1.

질문에 있는 데이터의 예를 들어보세요.

$ uniq -c -f 1 file
   1 18:56:54 Info: Starting
   3 18:56:55 Error: timed out
   1 18:56:58 Info: reconnected
   1 18:56:59 Error: timed out

답변2

줄 시작 부분의 개수에 만족한다면 uniq필요한 것은 다음과 같습니다.

$ uniq -f 1 -c log.txt 
      1 18:56:54 Info: Starting
      3 18:56:55 Error: timed out
      1 18:56:58 Info: reconnected
      1 18:56:59 Error: timed outhet

-f 1첫 번째 필드를 건너뛰고 -c행 수를 계산합니다.

필요한 정확한 형식을 얻으려면 uniq출력을 처리해야 합니다 sed. 예를 들면 다음과 같습니다.

$ uniq -f1 -c log.txt | 
    sed -E -e 's/^[[:space:]]+//;
               s/^([[:digit:]]+)[[:space:]]+(.*)/\2 (\1)/;
               s/ \(1\)$//' 
18:56:54 Info: Starting
18:56:55 Error: timed out (3)
18:56:58 Info: reconnected
18:56:59 Error: timed out

sed 스크립트는 -E기본 기본 정규식(BRE) 대신 확장 정규식(옵션), 즉 ERE를 사용합니다.

  • 각 줄에서 선행 공백을 제거합니다.
  • 각 줄의 시작 부분에 있는 모든 숫자를 괄호로 묶어 줄의 끝 부분으로 이동합니다.
  • 각 줄 끝에서 "(1)"이 있는 경우 제거합니다.

답변3

사용 유틸리티 다음과 같이 고유한 이벤트 수를 도출할 수 있습니다.

$ awk '
{t=substr($0,1+index($0,FS))}
prev != t {
  if (NR>1) {fx(line,knt)}
  knt = 0
  prev = t
}{
  line = $0
  knt++
}
END {fx(line,knt)}
function fx(a,b) {
  print a (b>1?sprintf("%s(%d)",OFS,b):"")
}
' file
18:56:54 Info: Starting
18:56:57 Error: timed out (3)
18:56:58 Info: reconnected
18:56:59 Error: timed out

노트:-

  • 선행 공백/연속 공백이 없다고 가정합니다.

답변4

주문하다

uniq -f 1 -c filename| awk '{print $2,$3,$4,$5,$1}'| awk '{if($NF > 1){$NF="("$NF")";print }else{$NF="";print }}'

산출

18:56:54 Info: Starting 
18:56:55 Error: timed out (3)
18:56:58 Info: reconnected 
18:56:59 Error: timed out 

관련 정보