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)로 설정 되면 f
false(0)로 설정됩니다. 각 줄을 읽을 때 f
true이면 현재 줄이 인쇄됩니다.
다른 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