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:%!gofmtr !{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
uimmediately reverts the replacement if the output isn't what you expected