How do I pipe the contents of my current buffer as input to a shell command in Vim?
Answer
:w !cmd
Explanation
The :w !cmd command sends the buffer's contents as standard input to an external command without modifying the buffer. This is fundamentally different from :%!cmd, which replaces the buffer with the command's output. Use :w !cmd when you want to pass your text to a tool for side-effect purposes — copying to the clipboard, counting words, validating syntax — while keeping the buffer intact.
How it works
:wwithout a filename normally writes to disk; with!cmd, it pipes to a process instead- The entire buffer is sent to
cmd's stdin - The buffer is not modified — the command's output is not inserted
- You can restrict the range:
:'<,'>w !cmdsends only the visually selected lines
Example
Count the lines and words in the current buffer:
:w !wc -l
Copy the buffer to the macOS clipboard:
:w !pbcopy
Run only the selected lines as a Python script:
:'<,'>w !python3
Tips
- To capture the output into the buffer, use
:r !cmd(read) or:%!cmd(filter) instead - On Linux/WSL, use
:w !xclip -selection clipboardor:w !xsel --clipboard --inputfor clipboard integration - Combine with a range:
:1,10w !sortsends lines 1–10 tosort(output appears below the command line, buffer unchanged) - The command runs in a shell, so you can use pipes:
:w !tr '[:upper:]' '[:lower:]' | wc -c