How do I filter a visual selection through an external shell command?
Answer
:'<,'>!command
Explanation
How it works
Vim can pipe selected text through any external shell command, replacing the selection with the command's output. This is one of Vim's most powerful features, connecting it to the entire Unix/Linux toolkit.
The workflow is:
- Select text in visual mode (any mode:
v,V, orCtrl-V) - Press
!(Vim enters command mode with'<,'>!pre-filled) - Type the shell command
- Press Enter
Vim sends the selected lines as stdin to the command and replaces them with stdout.
Powerful examples:
:'<,'>!sort- Sort the selected lines alphabetically:'<,'>!sort -n- Sort numerically:'<,'>!sort -u- Sort and remove duplicates:'<,'>!column -t- Align text into columns:'<,'>!python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))"- Format JSON:'<,'>!awk '{print NR": "$0}'- Add line numbers:'<,'>!tac- Reverse line order:'<,'>!uniq- Remove adjacent duplicate lines:'<,'>!bc- Evaluate mathematical expressions
This works with any command that reads stdin and writes stdout, making Vim extensible without plugins.
Example
Given this unsorted list selected with V:
banana
apple
cherry
apple
date
- Select all lines with
V4j - Type
!sort -uand press Enter
Result:
apple
banana
cherry
date
The lines are sorted alphabetically with duplicates removed. The original text is replaced in-place, and you can undo with u if needed.