Regarding keeping a pattern space comprising all text since the last match "Compiling", but there can be thousands of lines without an error. Would it be very inefficient? - no, it probably wouldn't any less efficient than any alternative approach such as doing 2 passes of the input file to identify the matching pairs of delimiters before starting printing and it'd have the advantage that it will work whether the input is stored in a file or coming from a pipe.
UsingProbably most efficient is just to use 2 calls to tac with awk if you're on a system that has tac:
$ tac file | awk '/error:/{f=1; print "---separator---"} f; /^Compiling/{f=0}' | tac Compiling File3 ... commands ... In file included from ... In file included from ... In file included from ... error: could not find A ---separator--- Compiling File5 ... commands ... In file included from ... In file included from ... In file included from ... error: could not find B ---separator---
Otherwise, just using any awk in any shell on every Unix box:
$ awk ' /^Compiling/ { buf="" } { buf = buf $0 "\n" } /^error:/ { print buf "---separator---" } ' file Compiling File3 ... commands ... In file included from ... In file included from ... In file included from ... error: could not find A ---separator--- Compiling File5 ... commands ... In file included from ... In file included from ... In file included from ... error: could not find B ---separator---
Alternatively, using GNU awk for multi-char RS and RT:
$ awk -v RS='\nerror:[^\n]+' -v ORS='\n---separator---\n' ' sub(/(^|.*\n)Compiling/,"Compiling") { print $0 RT } ' file Compiling File3 ... commands ... In file included from ... In file included from ... In file included from ... error: could not find A ---separator--- Compiling File5 ... commands ... In file included from ... In file included from ... In file included from ... error: could not find B ---separator---