Grep – Show Lines Until Certain Pattern [Duplicate]

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
endif

I 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?

  1. The question asks for a solution with grep which 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.

  2. 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 like grep: 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ützt
    
  3. The 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.

4

You can use sed for that:

sed -n '/if/,/endif/p' myfile
  • -n don'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 want
  • p print the matched lines
4

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' file

or use a more flexible tool such as pcregrep

pcregrep -M '(?s)\nif.*?\nendif' file

or perl itself

perl -00 -ne 'print if m/^if.*?endif/s' file

Alternatively, 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.

1
Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest