Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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?

share|improve this question
    
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 Nov 20 '12 at 9:40

4 Answers 4

up vote 10 down vote accepted

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.

share|improve this answer
    
+1 for the length :) In my particular example I don't have consecutive bars so this one is super easy to remember. –  jakub.g Nov 20 '12 at 9:30

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
share|improve this answer
    
+1 for being both concise and general. –  jw013 Nov 19 '12 at 20:13
    
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 Nov 21 '12 at 9:58

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.

Update

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.

share|improve this answer
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 Nov 19 '12 at 17:07

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

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

Sample data:

$ cat sample1.txt 
foo
bar
biz
baz
buz

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.

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

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.