How do I pipe selected text through an external command and replace it?
Answer
!{motion}command
Explanation
The ! operator in normal mode pipes text through an external shell command and replaces it with the output. This lets you leverage the entire Unix toolchain for text processing without leaving Vim.
How it works
- Press
!followed by a motion to select the text - Vim opens the command line with a range pre-filled
- Type the shell command
- The selected text is piped as stdin; stdout replaces it
Examples
" Sort the current paragraph
!ip sort
" Format current paragraph with fmt
!ip fmt -w 80
" Pretty-print JSON (whole file)
:%!python3 -m json.tool
" Sort the entire file
:%!sort
" Unique lines in selection
:'<,'>!sort -u
" Reverse lines in a paragraph
!ip tac
" Convert tabs to spaces
:%!expand -t 4
" Format C code with clang-format
:%!clang-format
Operator + motion examples
!5j sort " Sort from current line through 5 lines down
!G sort " Sort from current line to end of file
!{ fmt -w 72 " Format from current line to start of paragraph
Tips
- In visual mode, select text first, then press
!to filter just that selection - Use
!!to filter the current line through a command (equivalent to:.!) - The external command receives the text on stdin and Vim captures stdout
- This is one of the key philosophies of Unix Vim: small tools composed together