How do I send the contents of my buffer to a shell command without replacing the text?
Answer
:w !{cmd}
Explanation
The :w !{cmd} command writes the buffer contents to the stdin of an external shell command without modifying the buffer or saving to disk. This is fundamentally different from :%!{cmd} which replaces the buffer with the command's output — :w !{cmd} leaves your buffer untouched and just displays the command's output in Vim's command area.
How it works
:wnormally writes the buffer to a file, but when followed by!{cmd}, it pipes the buffer contents to the shell command's stdin instead- The buffer itself is not modified — the text stays exactly as it is
- The command's stdout is displayed below the status line
- You can use a range to send only specific lines:
:1,10w !wc -lsends just lines 1-10
Note the space between w and !. Without the space, :w! is a force-write to disk — a completely different command.
Example
Count the words in your buffer without leaving Vim:
:w !wc -w
Vim displays something like:
342
Run the buffer as a script:
:w !bash
Send selected lines to a command — visually select some lines, then:
:'<,'>w !python3
This executes just the selected lines as a Python script.
Copy the entire buffer to the system clipboard (on macOS):
:w !pbcopy
Tips
- Remember:
:w !cmdpipes to a command,:%!cmdfilters the buffer through a command (replacing contents). The space matters! - Use
:w !diff - %to see the diff between the buffer's current state and the saved file on disk — the-reads from stdin (the buffer) and%is the filename :w !sudo tee %is the classic trick for writing to a file you opened without root permissions- Combine with ranges for targeted operations:
:.w !bashexecutes only the current line as a shell command - The output is shown in Vim's message area — press
<CR>to dismiss it and return to editing - Use
:silent w !cmdto suppress the output if you don't need to see it