How do I pipe the entire buffer through an external shell command and replace its contents with the output?
Answer
:%!{command}
Explanation
The ! filter command in Vim sends a range of lines to an external program as standard input, then replaces those lines with the program's standard output. Using % as the range selects the entire file, making :%!{command} a one-shot way to transform the whole buffer using any shell tool.
How it works
%— the range covering all lines (equivalent to1,$)!— the filter operator: pipe range through an external command{command}— any shell command that reads from stdin and writes to stdout- The buffer contents are replaced with the command's output
- Undo with
urestores the original content
Example
Sort all lines alphabetically:
:%!sort
Format a JSON file with jq:
:%!jq .
Remove duplicate lines:
:%!sort -u
Base64-encode the buffer:
:%!base64
Tips
- Apply to a range instead of the whole file:
:'<,'>!sortsorts only the visually selected lines - Combine with a line address for a single line:
:.!datereplaces the current line with the current date - If the external command fails or produces no output, Vim restores the original lines and shows the error
- The filter approach lets you bring any CLI tool (awk, sed, python, jq, xmllint…) into your editing workflow without leaving Vim