Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

In Vim I often find I'm only interested in lines containing a certain string of text and want to delete all other lines.

It's easy to match lines containing a string:

:s/^.*foo.*\n//

What I normally end up doing is two passes, one to "flag" all the lines I want with a special first character:

:s/^\(.*foo.*\)$/X\1/

And in the second pass it's easy to do a negative match for one character in a fixed position, so I delete all the lines without my string thus:

:s/^[^X].*\n//

But isn't there a much more straightforward way to do this with just a single pass? What am I missing?

share|improve this question
    
I think this has been asked before despite my not finding it at the time: vim delete all lines that do NOT contain a certain word –  hippietrail Oct 30 '12 at 7:22
add comment

2 Answers

up vote 6 down vote accepted

This would delete all lines that don't contain foo.

:g/^\(.*foo\)\@!.*$/d

Instead, you could also use :v to reverse the sense of search pattern.

:v/\(foo\)/d

You can read more about the way :g and :v work here.

And more on defining ranges, use of metacharacters etc. for search and replace here.

share|improve this answer
    
It seems :g is one of very many vim commands I never learned before - thanks! (-: –  hippietrail Oct 28 '12 at 13:09
    
Why \( and \)? –  Bernhard Oct 28 '12 at 13:38
1  
+, ?, |, {, }, (, and ) must be escaped to use their special function. –  abhshkdz Oct 28 '12 at 13:40
    
I use :g and :v a lot. If, for some reason, :v doesn't stick you can use :g!. –  romainl Oct 28 '12 at 20:28
add comment

Well, if your aim is only to remove the lines with the text, that can be easily done with awk like so :

awk '/regex/{print}' filename

Meaning awk will act on filename. You can either pipe it to a new filename or the same filename, like this -

   awk '/regex/{print}' filename > filename.tmp && mv filename.tmp filename
share|improve this answer
    
While I do have vim installed on every platform I use, I usually only have awk when I'm on *nix. Lately I'm mostly on Windows. Hence I seek a vim-based answer. Thanks though. –  hippietrail Oct 28 '12 at 13:07
    
I just realised that my initial solution wouldn't work... so if you do every use this, you should do it this way! –  Kitchi Oct 28 '12 at 13:14
add comment

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.