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?
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.
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"
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'
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.
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.