Sorting lines in a file based on the number of words in each line
From Vim Tips Wiki
Here is one use of substitute with an expression (:help sub-replace-expression).
I needed to sort a file according to the number of words in each line. Using the
:s command, I inserted the number of words each line contains, at the beginning of the line.
To simplify sorting (using the excellent VisSort), instead of inserting a number, I put the corresponding character (number plus 64, so a line with one word will start with 'A').
Here is the expression I used:
:%s/^.*/\=nr2char(strlen((substitute(substitute(submatch(0), "\\S\\+", "x", "g"), "\\s","","g")))+64) . "\t" . submatch(0)
Explanation, from the inside out:
Replace all consecutive non space by a single x (each word is now a single x):
part1 = substitute(submatch(0), "\\S\\+", "x", "g")
Remove the spaces between "x":
part2 = substitute(part1,"\\s","","g")
Count the number of "x":
part3 = strlen(part2)
Get the ASCII char representing the number of words + 64:
part4 = nr2char(part3+64)
I replace all lines (^.*) by that ASCII char, followed by a tab and the initial line itself.
I can then sort, then remove all characters between the beginning of lines and the first tab.
To sort all file:
To remove prefix of letter and tab: