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.

I use vim to remove all lines except those that match a particular string, e.g.

:g!/[string that I want to remain in the editor]/d

Works great. But what I really want, and haven't found anywhere, is a way to use vim to remove all except for multiple strings.

For example, let's say I have a file open with the following information:

Dave came at 12PM
Lucy came at 11AM
Trish came at 5PM
John ate lunch at 2PM
Virgil left at 3PM
Dave left at 6PM

and I want to only be left with events that mention Dave and John -- what vim command could I use to just end up with:

Dave came at 12PM
John ate lunch at 2PM
Dave left at 6PM

I realize I can use command-line tools like findstr in Windows and others in *nix, but I'm in vim pretty often and haven't been able to some up with any regex or vim command that will do this. Thank you!

share|improve this question

3 Answers 3

up vote 6 down vote accepted

The :global command that you reference in your question actually doesn't just take literal strings, it handles any regular expression. So, you just need to come up with one that has two branches, one for John and one for Dave. Voila:

:g!/Dave\|John/d

Note that this simplistic one would also match Johnny; you probably want to limit the matches to whole keywords:

:g!/\<\(Dave\|John\)\>/d

Regular expressions are a powerful feature of Vim; it's worthwhile to learn more about them. Get started at :help regular-expression.

share|improve this answer
1  
OMG I forgot to escape the pipe when I tried that. I'll do that now! Thank you. –  Dave May 21 at 18:58
2  
That, or use the \v "very magic" modifier that lets you omit most backslashes, as in Lieven Keersmaekers's answer. –  Ingo Karkat May 21 at 19:00
    
That was it. I escaped everything in my regex but somehow overlooked the pipe. :) –  Dave May 21 at 19:02
    
To save a character, you can use :v instead of :g!. –  Kevin May 22 at 2:49

Following should do it

:v/\v(Dave|John)/d

Breakdown

:v                  matches all lines not containing the search expression 
/\vDave|John        search expression
/d                  execute delete on all those lines 
share|improve this answer

Use this:

:%s/^[^Dave|John].*\n//

Meaning:

%            means search the whole file
^            at the beginning of the line
[^Dave|John] something that isn't Dave nor John
.*           match anything
\n           new line character
//           replace with nothing
share|improve this answer
3  
Use of :s to remove entire lines is more cumbersome than the :g from the question. And that [^Dave|John] is nonsense. –  Ingo Karkat May 21 at 18:53

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.