How do I pipe a visual selection through an external command and replace it with the output?
Answer
:'<,'>!{cmd}
Explanation
Select lines in Visual mode, press !, and Vim sends those lines as stdin to an external shell command, replacing the selection with the command's stdout. This is Vim's filter mechanism — it turns any Unix tool into a text transformation you can apply to any range.
How it works
- Select lines with
V(line-wise visual mode) - Press
:— Vim auto-fills:'<,'> - Type
!{command}and press Enter - The selected lines are piped through the command and replaced with its output
Examples
Sort selected lines with custom options:
:'<,'>!sort -t, -k2 -n
Sorts CSV lines by the second column numerically.
Format JSON:
:'<,'>!python3 -m json.tool
Remove duplicate lines (preserving order):
:'<,'>!awk '!seen[$0]++'
Reverse the selected lines:
:'<,'>!tac
Column-align with column:
:'<,'>!column -t -s,
Tips
- The filter only works on whole lines — even if you select partial lines, Vim sends full lines to the command
:%!{cmd}filters the entire file through a command (no selection needed)!{motion}{cmd}works from Normal mode too:!ip sortfilters the current paragraph throughsort- If the command fails or produces no output, Vim replaces your selection with nothing — use
uto undo - This is one of Vim's most powerful Unix integration features — any tool that reads stdin and writes stdout becomes a Vim command