Printing the last window with sed
I have a log to process that is roughly structured like this:
... ... sentinel marker ... marker ... sentinel marker ...
I want everything between marker
and the next sentinel
, and I want the last such "window". The following is done:
sed -e "1{h;d} ; 2,109{H;d} ; 110{H;g} ; /sentinel/h ; \${g;q} ; N ; D" file.log
Here 110 is a rough (but consistent within a couple of lines) estimate of the space between marker
for this log, but I would have to recalculate that estimate for other logs, which is annoying.
I am wondering if there is a more elegant way to achieve this with sed
, i.e. automatically return the last window between marker
and sentinel
(I also agree with the answer, which shows why you can "t do this in sed
).
Thank.
PS I know this can be done in any number of languages, but I would like to use muscles sed
.
source to share
This might work for you (GNU sed):
sed '/marker/,/sentinel/{/marker/h;//!H};$!d;x' file
Hide the lines between marker
and sentinel
in the hold space (overwriting the old one with the new one) and at the end of the file print whatever is left in the hold.
EDIT:
The solution above satisfies the pairs marker
and sentinel
. If any of these are likely to be missing, use:
sed '/marker/,/sentinel/H;$!d;x;s/.*\(marker.*sentinel\).*/\1/p;d' file
This keeps all pairs marker/sentinel
in hold space, and at the end of the file deletes all but the last complete pair.
source to share
If you know there are no empty lines in the file, you can do:
sed -e '/^marker$/i\
\
' -e '/^sentinel$/a\
\
' input | awk '/sentinel/{l=$0}END{print l}' RS=
(Not sure if I would call it elegant: basically you insert blank lines between records and let awk RS do the heavy lifting. Unless you can guarantee there are no blank lines, before / after processing the data to ensure that:
sed 's/^/x/' input | sed -e '/^xmarker$/i\
\
' -e '/^sentinel$/a\
\
' | awk '/sentinel/{l=$0}END{print l}' RS= | sed 's/^x//'
(Of course, you could have avoided additional sed by wrapping them in existing sed and awk, but the idea is (I think) clearer.)
source to share