0

I have a log file with the following structure, some logs will contain line breaks like [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

So what I want to grep is the whole content of the log [query-id=123], but if I grep query-id=123, I can only get the lines with header [query-id=123] contentA: and [query-id=123] contentB:, the lines following the lines with header would be lost.

2 Answers 2

0

pcregrep has a Mulitline mode which you could use for that:

$ 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 is for horizontal space character. Also note the \b for word boundary without which query-id=123 would also match in query-id=1234. Or you could be more explicit and grep for [query-id=123] at the start of a line:

pcregrep -M '^\[query-id=123\].*(\n\h.*)*' your-file
0

With 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

More readable:

awk -v SECTION='\\[query-id=123\\]' '
/^\[query-id/ {
  HEADER=$0
}
HEADER ~ SECTION {
  print $0
}' file

Or, if the format of the header is always [query-id=<NUMBER>], you can provide only the number as the SECTION variable instead of the entire header:

$ 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

Readable:

awk -v SECTION='123' '
BEGIN {
  PATTERN=sprintf("^\\[query-id=%s\\]", SECTION)
}

/^\[query-id/ {
  HEADER=$0
}

HEADER ~ PATTERN {
  print $0
}' file

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .