I use this

cat foo.txt | sed '/bar/d'

to remove lines containing the string bar in the file.

I would like however to remove those lines and the line directly after it. Preferably in sed, awk or other tool that's available in MinGW32.

It's a kind of reverse of what I can get in grep with -A and -B to print matching lines as well as lines before/after the matched line.

Is there any easy way to achieve it?

  • 2
    Just for information: I'm analyzing logs in which entries are two-liners. So I want to find an entry matching the pattern and remove it as well as the next line. Hence I don't need to handle consecutive match lines, but thanks anyway for the completeness of your answers!
    – jakub.g
    Commented Nov 20, 2012 at 9:40

5 Answers 5


If you have GNU sed (so non-embedded Linux or Cygwin):

sed '/bar/,+1 d'

If you have bar on two consecutive lines, this will delete the second line without analyzing it. For example, if you have a 3-line file bar/bar/foo, the foo line will stay.

  • 1
    +1 for the length :) In my particular example I don't have consecutive bars so this one is super easy to remember.
    – jakub.g
    Commented Nov 20, 2012 at 9:30
  • 15
    sed '/bar/d' if you just want to "Remove line containing certain string" and not the next.
    – AJP
    Commented Apr 2, 2017 at 9:55
  • If I want to remove all the lines after math then?
    – Pandya
    Commented Feb 7, 2018 at 9:24
  • 2
    @Pandya That's different. You can use e.g. sed '/math/q' Commented Feb 7, 2018 at 12:44
  • 2
    @A.K. If you just want to delete the matching line, it's even simpler: sed '/bar/d' Commented Dec 21, 2018 at 7:36

If bar may occur on consecutive lines, you could do:

awk '/bar/{n=2}; n {n--; next}; 1' < infile > outfile

which can be adapted to delete more than 2 lines by changing the 2 above with the number of lines to delete including the matching one.

If not, it's easily done in sed with @MichaelRollins' solution or:

sed '/bar/,/^/d' < infile > outfile
  • The other plus in the AWK solution is that I can replace /bar/ with /bar|baz|whatever/. In sed that syntax doesn't seem to work.
    – jakub.g
    Commented Nov 21, 2012 at 9:58
  • 1
    @jakub.g , I have GNU sed (v4.4 now). Not sure about the others. What I know is that it uses "basic" regular expression syntax by default this is why your example didn't work. To achieve what you want you can either put a backslash in front of each vertical line or you can ask sed to use "extended" regular expressions. More information here: gnu.org/software/sed/manual/html_node/… . Please note that this is applicable to grep as well. Here's my own working example: echo $'0a\n1b\n2c' | sed '/0a\|1b/d'. Commented Jul 14, 2019 at 12:51

I am not fluent in sed, but it is easy to do so in awk:

awk '/bar/{getline;next} 1' foo.txt 

The awk script reads: for a line containing bar, get the next line (getline), then skip all subsequent processing (next). The 1 pattern at the end prints the remaining lines.


As pointed out in the comment, the above solution did not work with consecutive bar. Here is a revised solution, which takes it into consideration:

awk '/bar/ {while (/bar/ && getline>0) ; next} 1' foo.txt 

We now keep reading to skip all the /bar/ lines.

  • 1
    To replicate grep -A 100%, you also need to handle any number of consecutive bar lines correctly (by removing the whole block and 1 line after).
    – jw013
    Commented Nov 19, 2012 at 17:07

You will want to make use of sed's scripting capabilities to accomplish this.

$ sed -e '/bar/ { 
 }' sample1.txt

Sample data:

$ cat sample1.txt 

The "N" command appends the next line of input into the pattern space. This combined with the line from the pattern match (/bar/) will be the lines that you wish to delete. You can then delete normally with the "d" command.

  • How do I type a newline in console? Or this is script-only?
    – jakub.g
    Commented Nov 20, 2012 at 9:35
  • @jakub.g: with GNU sed: sed -e '/bar/{N;d}' sample1.txt
    – Cyrus
    Commented Jul 27, 2014 at 17:51

If any line immediately following a match should be removed then your sed program will have to consider consecutive matches. In other words, if you remove a line following a match which also matches, then probably you should remove the line following that as well.

It is implemented simply enough - but you have to look-behind a little.

printf %s\\n     0 match 2 match match \
                 5 6 match match match \
                 10 11 12 match 14 15  |
sed -ne'x;/match/!{g;//!p;}'


It works by swapping hold and pattern spaces for each line read in - so the last line can be compared to the current each time. So when sed reads a line it exchanges the contents of its buffers - and the previous line is then the contents of its edit buffer, while the current line is put in hold space.

So sed checks the previous line for a match to match, and if its ! not found the two expressions in the { function } are run. sed will get the hold space by overwriting the pattern space - which means the current line is then in both the hold and pattern spaces - and then it will // check it for a match to its most recently compiled regular expression - match - and if it does not match it is printed.

This means a line is only printed if it does not match and the immediately previous line does not match. It also foregoes any unnecessary swaps for sequences of matches.

If you wanted a version that could drop an arbitrary number of lines occurring after a match it would need a little more work:

printf %s\\n    1 2 3 4 match  \
                match match 8  \
                9 10 11 12 13  \
                14 match match \
                17 18 19 20 21 |
sed -net -e'/match/{h;n;//h;//!H;G;s/\n/&/5;D;}' -ep

...replace the 5 with the number of lines (including the matched line) that you would like to remove...


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .