With grep I know how to set the context to a fixed number of lines. Is it possible to show a context based on an arbitrary string condition, like set after-context to \"until th
It sounds like you need sed
:
sed -n '/pattern/,/^$/p' file
Don't print by default (-n
). For lines that match /pattern/
up to an empty line /^$/
, print.
Personally I like the answer from @William Pursell as the before context is often useful (eg when grepping for things in ini
files). If you actually want only the after context with awk
you can do this:
$ cat demo.ini
[foo]
aaa = 1
bbb = 2
ccc = 3
[bar]
eee = 8
fff = 0
ggg = 1
[baz]
xxx = 1
yyy = 0
zzz = 2
$ awk '/bar/,/^$/' demo.ini
[bar]
eee = 8
fff = 0
ggg = 1
$ awk '/fff/,/^$/' demo.ini
fff = 0
ggg = 1
$
Compare with the RS=
version:
$ awk '/bar/' RS= demo.ini
[bar]
eee = 8
fff = 0
ggg = 1
$ awk '/fff/' RS= demo.ini
[bar]
eee = 8
fff = 0
ggg = 1
A simple solution is:
awk '/pattern/' RS= input-file
Setting RS to the empty string makes awk treat blank lines as the record separator, and the simple rule /pattern/
causes awk to print any record that matches the pattern, which can be any extended regular expression.
Here's a (tested) awk
solution, separated onto multiple lines for readability:
awk '/pattern/ {do_print=1}
do_print==1 {print}
NF==0 {do_print=0}' input_file
This script will also print the blank line so it's easier to visually separate the different matched blocks. If you don't want the blank line, swap the 2 lines do_print==1 {print}
and NF==0 {do_print=0}
Explanation:
awk
: invoke the awk
tool - it evaluates the input one line at a time sequentially.'...'.
: everything enclosed by the single quotes is given to awk
as instructions. In this case we perform the quoted instructions on each line./pattern/ {do_print=1}
: whenever a line contains "pattern
", turn on the do_print
flagdo_print==1 {print}
: if the do_print
flag is set to on, print the current line.NF==0 {do_print=0}
: NF stands for Number of Fields. awk
delimits each line by spaces and tabs by default to break a line into fields. In this case trivially a blank line has no fields - so we turn off the do_print
flag to stop printing when we see a line with NF == 0