How do I filter a range of text through an external shell command directly in normal mode?
Answer
!{motion}{cmd}
Explanation
The ! operator in normal mode lets you pipe any motion's text through a shell command and replace it with the output. This is one of Vim's most powerful, lesser-known editing capabilities — turning any external Unix tool into an in-editor transformation.
How it works
!triggers the filter operator, which takes a motion (just liked,y, orc){motion}defines the range of text to filter (e.g.,ipfor inner paragraph,Gfor to end of file,3jfor 3 lines down){cmd}is the shell command that receives the text on stdin and must write the replacement to stdout- The selected lines are replaced with the command's output
The shorthand !!{cmd} filters just the current line (the first ! is the operator, the second is the motion for "current line").
Example
Given the buffer:
banana
apple
cherry
With the cursor on banana, pressing !ip sort<CR> filters the paragraph through sort:
apple
banana
cherry
Or press !!python3 -c "import sys; print(sys.stdin.read().upper(), end='')"<CR> to uppercase just the current line.
Tips
!ip sort -u— sort a paragraph and remove duplicate lines!Gpython3 -m json.tool— format JSON from cursor to end of file!ipsort -rn— sort a paragraph numerically in reverse order- Works in visual mode too: select lines with
V, then press!to enter filter mode