2

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?

1

2 Answers 2

11

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.

4
  • It seems :g is one of very many vim commands I never learned before - thanks! (-: Oct 28, 2012 at 13:09
  • Why \( and \)?
    – Bernhard
    Oct 28, 2012 at 13:38
  • 1
    +, ?, |, {, }, (, and ) must be escaped to use their special function.
    – abhshkdz
    Oct 28, 2012 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, 2012 at 20:28
0

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
2
  • 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. Oct 28, 2012 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, 2012 at 13:14

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