grep – show lines until certain pattern [duplicate]
Matthew Barrera
I am on Ubuntu 16.04 and I want to search files for let’s say “if” and I want to the output until “endif”. The file could look like this
if … SOME CODE
endifI can do this with grep -A9 if my_file | grep -B9 endif.
This doesn’t works if the “if” clause is larger than 9 and if several “if” clauses are in the same file and if the first grep command contains several “if” clauses. The option -m1 in the second grep doesn’t help. Nested “if” clauses can be ignored. Has somebody an idea, maybe not with grep?
Difference to How do I grep for multiple patterns on multiple lines?
The question asks for a solution with
grepwhich is answered already in the question:grep -A9 if my_file | grep -B9 endif. The solution doesn’t work in my case but would work in the case of the other question.The proposed grep solutions of the other question don’t work (with Ubuntu?):
grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstützt.which is something likegrep: a not protected ^ or $ is not supported with -Pz. I use the following:root:/tmp# cat file Some text begin Some text goes here. end Some more text root:/tmp# grep -Pzo "^begin\$(.|\n)*^end$" file grep: ein nicht geschütztes ^ oder $ wird mit -Pz nicht unterstütztThe proposed solutions search only for pattern which start at the beginning of the line if I interpret the proposed solution correctly. Even if I remove
^the command doesn't work.
3 Answers
You can use sed for that:
sed -n '/if/,/endif/p' myfile-ndon't print anything until we ask for it/if/find the first line with this,keep going until.../endif/this is the last line we wantpprint the matched lines
Traditional grep is line-oriented. To do multiline matches, you either need to fool it into slurping the whole file by telling it that your input is null terminated e.g.
grep -zPo '(?s)\nif.*\nendif' fileor use a more flexible tool such as pcregrep
pcregrep -M '(?s)\nif.*?\nendif' fileor perl itself
perl -00 -ne 'print if m/^if.*?endif/s' fileAlternatively, for matching structured input in a grep-like way, there's sgrep
sgrep '"if" .. ("endif") containing "SOME CODE"' file 3 A solution awk could look like: awk '/if/,/endif/' file
Of course, it is similar to the solution with sed.