我有一个具有以下结构的日志文件,一些日志将包含换行符,例如[query-id=123]
[query-id=123] contentA:
1. content
2. content
3. content
[query-id=124] contentC
[query-id=123] contentB:
1. contentB
2. contentB
所以我想要 grep 的是日志的全部内容[query-id=123]
,但是如果我 grep query-id=123
,我只能得到带有 header 的行[query-id=123] contentA:
,[query-id=123] contentB:
带有 header 的行后面的行将会丢失。
答案1
pcregrep
有一个M
ulitline 模式,您可以使用它:
$ pcregrep -M 'query-id=123\b.*(\n\h.*)*' your-file
[query-id=123] contentA:
1. content
2. content
3. content
[query-id=123] contentB:
1. contentB
2. contentB
\h
用于h
水平空间字符。另请注意\b
for 单词b
边界,没有它query-id=123
也会匹配query-id=1234
。或者你可以更明确地[query-id=123]
在行的开头使用 grep for :
pcregrep -M '^\[query-id=123\].*(\n\h.*)*' your-file
答案2
和awk
:
$ awk -v SECTION='\\[query-id=123\\]' '/^\[query-id/ {HEADER=$0} HEADER ~ SECTION {print $0}' file
[query-id=123] contentA:
1. content
2. content
3. content
[query-id=123] contentB:
1. contentB
2. contentB
更具可读性:
awk -v SECTION='\\[query-id=123\\]' '
/^\[query-id/ {
HEADER=$0
}
HEADER ~ SECTION {
print $0
}' file
或者,如果标头的格式始终为[query-id=<NUMBER>]
,您可以仅提供数字作为变量,SECTION
而不是整个标头:
$ awk -v SECTION='123' 'BEGIN {PATTERN=sprintf("^\\[query-id=%s\\]", SECTION)} /^\[query-id/ {HEADER=$0} HEADER ~ PATTERN {print $0}' file
[query-id=123] contentA:
1. content
2. content
3. content
[query-id=123] contentB:
1. contentB
2. contentB
可读:
awk -v SECTION='123' '
BEGIN {
PATTERN=sprintf("^\\[query-id=%s\\]", SECTION)
}
/^\[query-id/ {
HEADER=$0
}
HEADER ~ PATTERN {
print $0
}' file