로그 파일에서 한 줄의 패턴을 grep하고 다음 패턴이 나올 때까지 다음 n 줄을 인쇄합니다.

로그 파일에서 한 줄의 패턴을 grep하고 다음 패턴이 나올 때까지 다음 n 줄을 인쇄합니다.

log.txt 파일에 다음 내용이 포함되어 있다고 가정합니다.

[12] 03/31/21 08:33:30.080851 T(12581) _DBG message x 1
[12] 03/31/21 08:33:30.080851 T(34897) _DBG message y 1
[12] 03/31/21 08:33:31.241167 T(12344) _DBG message z 1
[12] 03/31/21 08:33:31.457612 T(34897) _DBG message y 2
                        test message line 2
                        test message line 3 
                        test message line 4 
[12] 03/31/21 08:33:31.78912 T(12344) _DBG message z 2
[12] 03/31/21 08:33:32.56341 T(34897) _DBG message y 3
[12] 03/31/21 08:33:33.12789 T(12581) _DBG message x 2
                        test message for x
[12] 03/31/21 08:33:33.78123 T(34897) _DBG message y 3
                        test message line 2
[12] 03/31/21 08:33:34.12342 T(12581) _DBG message x 3
[12] 03/31/21 08:33:34.56712 T(34897) _DBG message y 4

원하는 출력은 다음과 같아야 합니다.

[12] 03/31/21 08:33:30.080851 T(34897) _DBG message y 1
[12] 03/31/21 08:33:31.457612 T(34897) _DBG message y 2
                        test message line 2
                        test message line 3 
                        test message line 4 
[12] 03/31/21 08:33:32.56341 T(34897) _DBG message y 3
[12] 03/31/21 08:33:33.78123 T(34897) _DBG message y 3
                        test message line 2
[12] 03/31/21 08:33:34.56712 T(34897) _DBG message y 4

스레드 ID가 주어지면 해당 메시지에 속하는 줄 + 다음 몇 줄을 인쇄해야 합니다. 원하는 출력에서는 다른 모든 스레드 메시지가 제거됩니다.

아래에서 sed 명령을 시도했지만 다음 줄도 인쇄합니다(다른 스레드 메시지임).

sed -n -e '/T(34897)/,/_DBG/ p' log.txt 

다른 grep/awk/regex 명령을 시도했지만 이 작업을 수행할 수 없습니다. 도와주세요

답변1

$ awk -v t=34897 '/^\[/{f=($4=="T("t")")} f' file
[12] 03/31/21 08:33:30.080851 T(34897) _DBG message y 1
[12] 03/31/21 08:33:31.457612 T(34897) _DBG message y 2
                        test message line 2
                        test message line 3
                        test message line 4
[12] 03/31/21 08:33:32.56341 T(34897) _DBG message y 3
[12] 03/31/21 08:33:33.78123 T(34897) _DBG message y 3
                        test message line 2
[12] 03/31/21 08:33:34.56712 T(34897) _DBG message y 4

f로 시작하는 줄을 볼 때마다 해당 줄에 "found" 플래그가 설정됩니다 [. 행의 네 번째 필드 T(<target value>)가 true(1)로 설정 되면 ffalse(0)로 설정됩니다. 각 줄을 읽을 때 ftrue이면 현재 줄이 인쇄됩니다.

다른 awk 스크립트와 마찬가지로 다른 형식으로 보고 기본값에 덜 의존하여 덜 간단하고 명확하게 만들고 싶다면 GNU awk를 사용하여 보기 좋게 인쇄할 수 있습니다(참고: 다른 형식 대신 gawk여야 합니다). awk 변형)은 다음과 같습니다 awk -o- ....

$ awk -o- -v t=34897 '/^\[/{f=($4=="T("t")")} f' file
/^\[/ {
        f = ($4 == "T(" t ")")
}

f {
        print
}

답변2

이 awk 스크립트를 사용하세요:

BEGIN {
  doprint = 0
  marker = "T("thread")"
}

$1 ~ /\[[0-9]+\]/ {
   if( $4 == marker ) {
      doprint = 1
   } else {
      doprint = 0
   }
}

doprint==1 { print }

다음과 같이 호출됩니다.

$ awk -v thread="34897" -f 642963.awk input.txt
[12] 03/31/21 08:33:30.080851 T(34897) _DBG message y 1
[12] 03/31/21 08:33:31.457612 T(34897) _DBG message y 2
                        test message line 2
                        test message line 3
                        test message line 4
[12] 03/31/21 08:33:32.56341 T(34897) _DBG message y 3
[12] 03/31/21 08:33:33.78123 T(34897) _DBG message y 3
                        test message line 2
[12] 03/31/21 08:33:34.56712 T(34897) _DBG message y 4

답변3

먼저 필드 기반 정규식을 공식화하는 데 도움이 되는 몇 가지 보조 변수를 정의합니다.

# definition of a unit space
_s_='[:space:]'

# regex for a space char and nonspace char
s="[$_s_]" S="[^$_s_]"

# a field is a run of nonspaces followed by a run of spaces
F="$S\{1,\}$s\{1,\}"

   id=34897

sed -ne ":top
  /^\[$S*$s$s*\($F\)\{2\}T($id)$s/{
    :nxt
      p;n
    /^$s/b nxt
    b top
  }
" file

관련 정보