Vim Recipes Editing Sorting Text

Sorting Text

Problem

You want to sort a selection of text or an entire whole file.

For example, if you've made a list of your books with one title per line, you'd like to organise it alphabetically.

Solution

Vim version 7 introduced a :sort command. So if you're using v7 or later you can sort an entire file using :sort.

You can find your Vim version number with the :version command. The first line of output contains the version number, e.g. VIM - Vi IMproved 7.2 (2008 Aug 9, compiled Mar 19 2009 15:27:51), which indicates version 7.2.

If you're using an older version of Vim you'll need an external sort utility. Linux/UNIX users should already have sort installed. You can sort the entire file by executing :!%sort, which filters the file through the external sort utility.

To sort part of a file:

  1. Select the area you're interested in.
  2. Hit : and Vim will display :'<,'>' which refers to your selection.
  3. Type !sort (i.e. execute :'<,'>!sort).

Discussion

Both methods above sort lines alphabetically. If you require a different type of sorting you need to pass options to the command.

If you're using Vim 7+:

:sort!
Reverses the sort order, i.e. sorts in descending order: z-a, 100-0.
:sort flags
The sort command can be followed by a series of flags which can be combined in any order:
n
Sorts by the first decimal number in the line.
i
Ignores case while sorting.
u
Deletes duplicate lines (keeps unique lines).
:sort /pattern/
Ignore text matching pattern when sorting.

For example, the following table describes how the set of data in the Original column is transformed for the given invocations of :sort.

Original :sort! :sort in :sort i /^./}
ant 1 zebra 12 ant 1 zebra 12
Dog 7 frog 11 fish 6 fish 6
cow 8 fish 6 Dog 7 ant 1
fish 6 cow 8 cow 8 Dog 7
frog 11 ant 1 frog 11 cow 8
zebra 12 Dog 7 zebra 12 frog 11

If you're using the external sort utility the options are similar. See man sort for the details. Common invocations are:

%!sort -u
Delete duplicate lines.
%!sort -f
Ignore case when sorting.
%!sort -r
Reverse sort order.