awk를 사용하여 파일에서 매우 특정한 부분 추출

awk를 사용하여 파일에서 매우 특정한 부분 추출

나는 사람들이 나를 전화 회의에 끌고 가거나 전체 파일을 수집하는 대신 쉽게 보낼 수 있도록 디버그 로그의 중요한 부분을 추출하는 스크립트(실제로는 한 줄 스크립트)를 작성하려고 합니다. 정보를 얻기 위해 less나 vi에서 무엇을 해야 하는지 알려줄 수 있지만 가능하다면 명령으로 사용하고 싶습니다.

존재하다 less:

$ less filename
G
?Server\ version
/SEVERE
[read line including first match for SEVERE from this point, stop reading when get to next instance of SEVERE]

이 작업을 수행하기 위해 명령 을 작성하려고 했지만 awk잘 되지 않습니다.

이것은 내가 얻은 가장 가까운 결과이지만 작동하지 않습니다.

awk '{if (/Server version/) {chunk=""} else {chunk=chunk $0 RS}} END {printf "%s", chunk}'  filename | awk '/SEVERE/,/SEVERE/'

awk마지막에 인쇄하고 싶은 부분의 시작과 끝 부분에 동일한 패턴을 사용하는 것을 좋아하지 않는 것 같습니다.

다른 도구를 사용할 의향이 있지만 사용 사례에서는 RHEL7에서 기본적으로 제공되는 유틸리티를 사용해야 합니다.

이 정보가 도움이 된다면 Apache Tomcat 디버그 로그를 살펴보겠습니다.

답변1

SEVERE내가 올바르게 이해했다면 첫 번째 발생과 마지막 발생 이후 다음 발생 사이의 줄을 출력하고 싶습니다 Server version.

입력 파일 예:

Server version
SEVERE
ignore
SEVERE
Server version
ignore
SEVERE
important
stuff
SEVERE 
ignore
SEVERE
awk '
  /Server version/{ chunk="" }
  /SEVERE/{ logme=(chunk=="") }
  logme{ chunk=chunk $0 RS }
  END{ printf "%s", chunk }
' file

산출:

SEVERE
important
stuff

답변2

여러 줄 개요: grep을 사용하여 줄 번호를 인쇄하고 추출한 후 awk를 사용합니다.

grep -n SEVERE filename | head -n 2 | cut -d ':' -f1

그러면 "SEVERE"가 포함된 처음 2개의 줄 번호 [a, b]가 출력되고 awk는 SEVERE와 중간 줄을 쉽게 인쇄할 수 있습니다.

awk 'NR>=a && NR<=b {print $0;}' filename

이는 쉽게 스크립트로 작성할 수 있지만 로그 파일을 두 번 통과해야 합니다.

관련 정보