vimtricks.wiki Concise Vim tricks, one at a time.

How do I sort a range of lines by piping them through an external sort command using the ! operator?

Answer

!{motion}sort

Explanation

The ! operator in Vim filters a motion's text through an external shell command, replacing it with the output. Unlike :%!sort which operates on the entire file, !{motion}sort lets you use Vim's full motion vocabulary to precisely target the lines you want sorted — a paragraph, a function body, or any arbitrary range.

How it works

  • ! — the filter operator, like d or y but pipes text to a shell and replaces it with stdout
  • {motion} — any Vim motion: ap (a paragraph), 5j (5 lines down), ip (inner paragraph), G (to end of file)
  • sort — the shell command; Vim passes the selected lines on stdin and replaces them with the output

After pressing !{motion}, the status line shows ! — type the command and press <CR>.

Example

Given an unsorted import block:

zlib
apache
babel
click

With the cursor anywhere in the block, type !apsort<CR> to sort the paragraph:

apache
babel
click
zlib

Tips

  • !apsort -u — sort and deduplicate with the sort -u flag
  • !Gsort -n — numerically sort from cursor to end of file
  • !{motion}uniq — remove adjacent duplicate lines
  • !!sort — filter just the current line (any command that accepts stdin)
  • The count prefix works too: 5!!sort filters 5 lines starting at the cursor

Next

How do I enable matchit so % jumps between if/else/end style pairs?