Reputation: 2583
I've got a program which prints to stdout some data in the following format:
$ ./my_program
foo
line1
line2
line3
bar
line1
foo
line1
line2
baz
line1
line2
I want to filter it, so it only prints sets of non-empty lines starting with some matching string. Something like that:
$ ./my_program | grep -A* foo
foo
line1
line2
line3
foo
line1
line2
Unfortunately I can't just use stuff like -A2
or -A3
because number of lines may differ. Are there any built-in feature or a simple one-liner to do it?
Upvotes: 0
Views: 68
Reputation: 52371
With sed:
./my_program | sed '/foo/,/^$/!d'
This deletes anything that is outside of the address range /foo/,/^$/
– lines between those matching foo
and an empty line.
This works almost the same for awk, with the logic inverted (print if in range, instead of delete if not in range):
./my_program | awk '/foo/,/^$/'
Upvotes: 1
Reputation: 50795
With awk, read the file in paragraph mode, and print paragraphs matching ^foo
.
$ awk 'BEGIN{RS="";ORS="\n\n"} /^foo/' file
foo
line1
line2
line3
foo
line1
line2
$
Upvotes: 3
Reputation: 17028
This should print the lines according to your description:
$ awk '/^$/{f=0}/foo/{f=1}f'
foo
line1
line2
line3
foo
line1
line2
This uses a flag (f
) to indicate the search string was found. The flag is reset after an empty line. But the example you gave contains an empty line between the matches, so that would be something like this:
$ awk '/^$/{if (f) print; f=0}/foo/{f=1}f'
foo
line1
line2
line3
foo
line1
line2
Upvotes: 1