두 행 사이의 데이터를 추출하는 명령

두 행 사이의 데이터를 추출하는 명령

로그 파일의 줄 번호부터 시작하여 예외와 해당 스택 추적을 추출해야 합니다. 나는 오류의 시작 라인 번호를 알고 있습니다. 아래 예에서 스택 추적이 끝나는 위치를 어떻게 알 수 있습니까? 당신의 도움을 주셔서 감사합니다


-------
2016-10-07 15:49:07,537 ERROR 일부 예외
 스택 추적 라인 1
 스택 추적 라인 2
 .
 .
 스택 추적 라인 n
2016-10-07 15:49:07,539 디버그 ㅋㅋㅋ ㅋㅋㅋ
2016-10-07 15:49:07,540 디버그 ㅋㅋㅋ ㅋㅋㅋ

답변1

요약하자면, 지정한 줄 번호로 시작하여 날짜로 시작하는 첫 번째 줄 바로 직전까지 계속되는 줄을 인쇄하려고 합니다. 귀하의 예에서 출발선은 3입니다. 이 경우:

$ awk '{if (NR==3)f=1; else if (/^[0-9-]{10} /)f=0} f{print}' trace.log
2016-10-07 15:49:07,537 ERROR Some exception
 stacktrace line 1
 stacktrace line 2
 .
 .
 stacktrace line n

위 코드는 다음과 같이 작동합니다.

  • if (NR==3)f=1

    지정한 줄 번호에서 변수를 f1로 설정합니다.

  • else if (/^[0-9-]{10} /)f=0

    다른 줄에서는 f줄이 숫자 또는 대시 뒤에 공백이 오는 10개의 문자로 시작하는 경우 0으로 설정합니다. 즉, f날짜처럼 보이는 것으로 시작하는 첫 번째 줄을 0으로 설정합니다.

    필요한 경우 날짜의 시작을 식별하기 위해 더 복잡한 정규식을 사용할 수 있습니다. 예를 들어, 다음에서는 줄이 데이터처럼 보이는 항목으로 시작하고 그 뒤에 공백, 시간처럼 보이는 항목, 쉼표가 와야 합니다.

    awk '{if (NR==3)f=1; else if (/^[0-9-]{10} [0-9:]{8},/)f=0} f{print}' trace.log
    

    이에 대한 추가 개선이 가능합니다.

  • f{print}

    0이 아닌 경우 f해당 행을 인쇄합니다.

    f{print}간결하게 하기 위해 just 로 대체할 수 있습니다 f. 이는 동작을 명시적으로 지정하지 않으면 기본 동작이 print사용되기 때문에 가능합니다.

대안

awk의 일부 버전은 {10}. 시스템에 그런 경우가 있으면 다음을 시도해 보십시오.

awk '{if (NR==3)f=1; else if (/^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] /)f=0} f{print}' trace.log

답변2

모든 스택 추적 줄이 공백(공백/탭)으로 시작한다고 가정하면 [[:blank:]]줄 시작 부분( )에서 일치시킬 수 있습니다( ) ^.

grep '^[[:blank:]]' file.log

답변3

추출하려는 추적이 의 라인 2에서 시작 trace.log하고 그 끝이 YYYY-MM-DD 형식의 날짜로 시작하는 줄로 표시되는 경우(추적에는 그러한 줄이 없습니다)

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log

라인 2의 모든 라인을 인쇄합니다~을 통해N+3(날짜로 시작하는 추적 뒤의 첫 번째 줄). 마지막 줄을 원하지 않으므로 위의 내용을 마지막 줄을 제거하는 명령에 파이프하십시오.

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | head -n -1

또는

sed -nE '2,/^[0-9]{4}-[0-9]{2}-[0-9]{2} /p' trace.log | sed '$d'

날짜를 검색해야 하는 경우그리고 시간을 선택한 다음 다음을 검색하세요.

^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}

관련 정보