로그의 일부를 추출하는 방법

로그의 일부를 추출하는 방법

다음과 같은 로그 파일이 있습니다.

Event
Process 1
Process 2
End event success
Event 
Process 1
Process 3
End event error
Event
Process 1
Process 5
End event success
Event
Process 1
Process 7
End event success
Event 
Process 2
Process 4
End event error

다음과 같은 오류 이벤트를 유지하고 싶습니다.

Event 
Process 1
Process 3
End event error
Event 
Process 2
Process 4
End event error

시도해 보았 cat Event.log | awk '/Event/,/End event error/'으나 원하는 대로 되지 않았습니다.

답변1

이것은 작동합니다:

awk '/^Event/{n=1} {lines[n++]=$0} /^End event error/{for(i=1;i<n;++i) print lines[i]}' Event.log

설명: "이벤트" 이후의 모든 행을 배열에 저장하고 "이벤트 종료 오류"가 발생하면 인쇄합니다.

답변2

sed추출하고 싶지 않은 모든 항목을 제거 하려면 다음을 수행하십시오.

$ sed '/^Event$/,/^End event success$/d' file
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error

답변3

$ perl -l -n -e 'BEGIN { $/ = "\nEvent" };
                 print "Event$_" if /End event error/' input.log 
Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error

\nEvent레코드 구분 기호( ) 로 사용되며 $/"종료 이벤트 오류"가 포함된 레코드를 인쇄합니다.

참고: Perl에서 레코드 구분 기호는 대소문자를 구분하는 고정 문자열입니다(즉, 정규 표현식이 아님).

각 레코드 사이에 빈 줄을 원할 경우(단락으로 후처리하기 쉽도록) 인쇄 문을 로 변경합니다 print "\nEvent$_" if ....

답변4

사용행복하다(이전 Perl_6)

~$ raku -e 'for lines.join("\n").split(/ \n <?before Event >/) { .put if .words[*-1] eq "error" };'  file

#OR

~$ raku -e '.put if .words[*-1] eq "error" for lines.join("\n").split: / \n <?before Event >/;'  file

Raku는 Perl 계열의 프로그래밍 언어입니다. 간단히,

  1. Auto-chomped lines는 읽어들여 \n개행 문자와 연결됩니다. 출력 끝에 추가 줄 바꿈을 추가하는 것에 신경 쓰지 않는다면 slurp여기에서 대신 사용할 수 있습니다.lines.join("\n")\n
  2. 데이터는 개행 문자가 삽입된 기존 레코드에 저장됩니다 split(전향 예측).\n<?before Event>
  3. 즉 , 공백으로 구분된 마지막 단어가 "error"로 기록됩니다 put.if words[*-1] eq "error"[*-1][참고: 다음 명령을 사용하면 레코드 어디에서나 대소문자를 구분하지 않는 "오류"가 있는 레코드를 반환할 수 있습니다 if m:i/error/.]

입력 예:

Event
Process 1
Process 2
End event success
Event
Process 1
Process 3
End event error
Event
Process 1
Process 5
End event success
Event
Process 1
Process 7
End event success
Event
Process 2
Process 4
End event error

예제 출력:

Event
Process 1
Process 3
End event error
Event
Process 2
Process 4
End event error

레코드가 올바르게 분할되었는지 확인하기 위해 중간 항목을 볼 수 있습니다( if위의 조건을 제거하고 추가 raku).

~$ raku -e '.raku.put for lines.join("\n").split: / \n <?before Event>/;'  file
"Event\nProcess 1\nProcess 2\nEnd event success"
"Event\nProcess 1\nProcess 3\nEnd event error"
"Event\nProcess 1\nProcess 5\nEnd event success"
"Event\nProcess 1\nProcess 7\nEnd event success"
"Event\nProcess 2\nProcess 4\nEnd event error"

재미삼아 탭 에 join/를 입력하면 매우 간단한 출력을 얻을 수 있습니다(입력 파일에 탭이 없다고 가정).split\t

~$ raku -e '.put if .words[*-1] eq "error" for lines.join("\t").split: / \t <?before Event>/;' file
Event   Process 1   Process 3   End event error
Event   Process 2   Process 4   End event error

https://docs.raku.org
https://raku.org

관련 정보