Delete lines below, excluding the line with match pattern

One can use sed '/pattern/Q' or sed '/pattern/,$d' to delete lines below a match pattern, but it also deletes the line containing the match pattern.

How to exclude the line containing the match pattern, and only delete the lines below it?

Asked By: Sadi

||

This should do it

sed -n '/pattern/{p;q};p'

The -n switch tells sed not to print by default.

The {p;q} says that if the pattern is observed, print the line and quit.

The ;p is the default action when no match has been found yet, and that is to print.

Answered By: bxm

Using awk:

$ awk 'NR==1,/pattern/'

The following command would print nothing if pattern is not found.

$ awk '{a = a $0 ORS}/pattern/{printf "%s", a}'

Using pcregrep:

$ pcregrep -M "(.*n)*.*pattern"
Answered By: Prabhjot Singh

You’re over-complicating this by using Q, which is one of the Commands Specific to GNU sed:

Q [exit-code]

This command accepts only one address.

This command is the same as q, but will not print the contents of pattern space. Like q, it provides the ability to return an exit code to the caller.

If you don’t want this special behaviour (i.e. you do want to print the contents of the matched pattern space before quitting), use the regular q command:

sed '/pattern/q'
Answered By: steeldriver

awk is a better choice than sed for tasks like this for simplicity, clarity and portability, e.g. to delete all lines below some line that matches a regexp (a 3 in this case):

$ seq 10 | awk '{print} /3/{exit}'
1
2
3

or if you want to also delete the matching line then move where the regexp is tested to before instead of after the print:

$ seq 10 | awk '/3/{exit} {print}'
1
2

or we can delete the 4 lines after a 3 appears by:

$ seq 10 | awk 'NR>n{print} /3/{n=NR+4}'
1
2
3
8
9
10

or alternatively using idiom "f" from printing-with-sed-or-awk-a-line-following-a-matching-pattern:

$ seq 10 | awk 'c&&c--{next} /3/{c=4} {print}'
1
2
3
8
9
10

Those commands will all work using any awk on every Unix box and it’s trivial to do anything similar you may want to do.

Answered By: Ed Morton

Using Perl:

~$ seq 10 | perl -pe 'last if /3/'
1
2

#OR:

~$ seq 10 | raku -ne '/3/ ? last : print $_;'
1
2

Using Raku (formerly known as Perl_6):

~$ seq 10 | perl -pe 'last if /3/'
1
2

#OR:

~$ seq 10 | raku -ne '/3/ ?? (last) !! (put $_);'
1
2

Perl and Raku borrow many of the command-line flage conventions from sed and awk. Above the -pe flags run the code linewise over input with autoprinting; the -ne flags run the code linewise over input without autoprinting. In all four answers above last is used exit the linewise loop. There are minor differences between Perl and Raku’s ternary operators, chiefly because Raku deploys the : colon for other aspects of the language.

https://perldoc.perl.org
https://docs.raku.org

Answered By: jubilatious1
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.