I\'m looking for a quick and easy one-liner to extract all brace-delimited text-blocks containing a search string from a text file. I\'ve just about googled myself crazy on
Here is a modified version of this gem from 'leu' (10x leu for enlighten us). This one is doing something very similarly. Extract everything between which begin with 'DEC::PKCS7[' and ending with ']!':
cat file | sed '/^DEC::PKCS7\[/{s///; :1; /\]\!$/!{N; b1;}; s///;};'
Explanation:
/^DEC::PKCS7\[/ # if current line begins with 'DEC::PKCS7[' then execute next block
{ # start block
s///; # remove all upto 'DEC::PKCS7['
:1; # label '1' for code to jump to
/\]\!$/! # if the line does not end with ']!' then execute next block
{ # start block
N; # add next line to pattern space
b1; # jump to label 1
}; # end block
s///; # remove all from ']!' to end of line
}; # end block
Notes:
This gnu-awk should work:
awk -v RS='[^\n]*{|}' 'RT ~ /{/{p=RT} /event/{ print p $0 RT }' file
blabla {
blabla
blablaeventblabla
}
RS='[^\n]*{\n|}'
sets input record separator as any text followed by {
OR a }
. RT
is the internal awk variable that is set to matched text based on RS
regex.
User 999999999999999999999999999999 had a nice answer using sed
which I really liked, unfortunately their answer appears to have disappeared for some reason.
Here it is for those who might be interested:
sed '/{/{:1; /}/!{N; b1}; /event/p}; d' filepath
Explanation:
/{/ if current line contains
{then execute next block
{ start block
:1; label for code to jump to
/}/! if the line does not contain
}then execute next block
{ start block
N; add next line to pattern space
b1 jump to label 1
}; end block
/event/p if the pattern space contains the search string, print it
(at this point the pattern space contains a full block of lines
from
{to
})
}; end block
d delete pattern space