vimtricks.wiki Concise Vim tricks, one at a time.

How do I replace a line (or range) with the output of a shell command in Vim?

Answer

:.!{cmd}

Explanation

:.!{cmd} filters the current line through a shell command and replaces it with the output. Vim sends the line as stdin to {cmd} and swaps it with stdout — turning any Unix utility into an in-place text transformer without leaving the editor.

How it works

  • : begins an Ex command
  • . is the current line as the range (. = current, % = whole buffer, 5,15 = lines 5–15)
  • !{cmd} pipes the range through a shell command; stdout replaces the original range
  • The content being filtered is sent as stdin, so many tools work naturally

Example

Insert today's date by positioning the cursor on an empty line:

:.!date

Before:


After:

Mon Feb 24 09:15:00 UTC 2026

Prettify a minified JSON line under the cursor:

:.!python3 -m json.tool

Sort a block of import statements (lines 1–10):

:1,10!sort

Tips

  • :%!{cmd} filters the entire buffer — useful for formatting whole files: :%!jq . or :%!gofmt
  • r !{cmd} is the read-only variant: it inserts command output after the cursor line without replacing anything
  • Combine with visual mode: select lines, then press ! and type a command — the range is pre-filled
  • Undo with u immediately reverts the replacement if the output isn't what you expected

Next

How do I define or modify a macro directly as a string without recording it?