Note that there are some explanatory texts on larger screens.

plurals
  1. POBash script to select a range starting with a pattern spanning two lines and ending in a blank line. Sed?
    text
    copied!<p>I have a file that among other things contains entries of the following form:</p> <pre><code>2012-01-12 22:20:21,638 INFO [Tracer] something.of.interest ...some number of additional lines... &lt;&lt;a blank line&gt;&gt; ...other stuff... </code></pre> <p>I want to pick out only blocks of text where the first line contains [Tracer] and the second line is contains <em>something.of.interest</em>, ending with a blank line an unknown number of lines after the second line. Changing the format of the file is not an option.</p> <p>I can use sed to pick out the entire block by doing something similar to:</p> <pre><code>gsed -n '/^[0-9]\{4\}[^\[]*\[Tracer\]/,/^$/ p' /path/to/file/to/parse </code></pre> <p>This picks the entire block as intended but it matches entries where the second line doesn't contain something.of.interest. </p> <p>I can use N to acquire the next line and then match across current and next line, and I can make this work to select the first two lines only when I see both [Tracer] and something.of.interest separated by \n, however I can't seem to figure out how to grab the following lines until I hit a newline. In pseudo-sed I want to do something like this:</p> <pre><code>/look for Tracer line 1/{ N /look for \n.*something.of.interest/ }, /look for blank line for end of range/ p </code></pre> <p>Sadly this doesn't actually work, typically I get and 'unknown command' message. </p> <p>Is there a way to define a range in sed using patterns where beginning and end could be multi-line patterns?</p> <p>The solution ultimately needs to operate on Solaris 5.10. GNU sed (gsed) is available, as is awk if that is a better choice in this case.</p> <p>Suggestions much appreciated.</p> <p><strong>UPDATE</strong></p> <p>It seems I can do it in awk, although the result is mildly horrific. I'd very much like a more elegant solution, still for reference here is an awk script that will find the lines of interest:</p> <p>1) Create a file something.awk, where the first line is the regexp to match line 1:</p> <pre><code>/\[Tracer\]/ { l1=$0 if (getline &lt;= 0) { print "getline failed" exit 1 } if (index($0, L2MARKER) &gt; 0) { print l1 print $0 stop=0 while(stop != 1) { if (getline &lt;= 0) { print "getline failed :( ERRNO:" + ERRNO exit 1 } print; if (length($0) == 0) { stop = 1 } } } } </code></pre> <p>2) Invoke from shell similar to <em>awk -f something.awk L2MARKER='something.of.interest' the.file.to.parse</em></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload