← back to latest

Keep only the lines that match and delete the rest

COMMAND:v/pattern/dKeep only the lines that match and delete the rest

anatomy

:
Enter command-line mode.
v
The inverse global command. Marks every line in the range that does NOT match the pattern. Short for :global! and it takes no bang of its own.
/pattern/
The pattern to test each line against. Any search pattern works, including anchors, character classes, and alternation. The slashes are delimiters, not part of the pattern.
d
The Ex command run on each marked line. Here, delete. Vim marks every line first, then runs d on the marks, so deleting lines never shifts the ones still queued.

In the buffer

Before:

2026-09-15 10:02 INFO  worker started
^
2026-09-15 10:04 DEBUG cache warm, 812 keys
2026-09-15 10:07 ERROR upload failed: timeout
2026-09-15 10:09 INFO  retry scheduled
2026-09-15 10:11 ERROR upload failed: timeout
2026-09-15 10:15 INFO  worker idle

After typing :v/ERROR/d:

2026-09-15 10:07 ERROR upload failed: timeout
2026-09-15 10:11 ERROR upload failed: timeout
^

Six lines in, two lines out, with the cursor left at the bottom of what remains.

When you would reach for it

You pasted a log, a test report, or a long config dump into a buffer and only a handful of lines matter. Scrolling and deleting by hand works until the file is four hundred lines long, at which point you start missing lines. :v inverts the question: instead of hunting for what to remove, you describe what to keep and vim discards everything else. It is the fastest way to turn a wall of output into the six lines you were actually reading it for.

Gotchas

  • If the pattern matches nothing, :v marks every line and you get an empty buffer. This is consistent behavior, not a failure, so vim reports no error. Press u once and the whole thing comes back, because the entire global command is a single undo block.
  • The pattern is case sensitive unless 'ignorecase' is set. :v/error/d against a buffer of uppercase ERROR lines deletes all of it. Test the pattern with / first and count the matches before you run the deletion.
  • :v has no ! form. :v!/pattern/d fails with E477: No ! allowed. The inverse of :v is plain :g, and :g! is the long spelling of :v.
  • Without a range, :v operates on the whole file, not from the cursor down. Prefix a range to limit it: :10,40v/pattern/d.

Variants

/ERROR
:v//d

An empty pattern reuses the last search, so you can search first, confirm the matches with n, then filter with five keystrokes.

:v/ERROR\|WARN/d

Alternation keeps more than one kind of line. In the log above this leaves the two ERROR lines and any WARN lines standing.

:g/^$/d

The same engine pointed the other way: mark every line matching “empty line” and delete those. :g and :v differ only in which lines get marked.

lineage

The global command came from ed, where g and v were already a matched pair before vi existed. Bill Joy's ex inherited both, and vim inherited them from ex. The same ed lineage gave Unix the name grep, from the command g/re/p: globally find a regular expression and print it. :v is that engine with the test flipped.

-- INSERT --vim-hacks.com018-018-keep-only-matching-lines.html
utf-81,1All