Unix sort of version numbers
I have a list of version numbers, let's say for instance that they are in a file versions.txt
1.2.100.4
1.2.3.4
10.1.2.3
9.1.2.3
I wish to sort them so that they are sorted by version. i.e:
1.2.3.4
1.2.100.4
9.1.2.3
10.1.2.3
I have tried using various sort commands using the "k" parameters, but do not really understand it well enough to pull it off. Any help would be appreciated.
The -V
option is the nicest, but I wanted to stay away from installing new/other software since my sort didn’t have that option.
This is the command that worked for me in the end:
sort -t. -k 1,1n -k 2,2n -k 3,3n -k 4,4n test.txt
From comments:
- To reverse the order:
sort -t. -k 1,1nr -k 2,2nr -k 3,3nr -k 4,4nr
- To skip the
v
prefix:sort -t. -k 1.2,1n -k 2,2n -k 3,3n -k 4,4n
sort -V versions.txt
From man sort
:
-V
,--version-sort
natural sort of (version) numbers within text
See also Details about version sort.
BSD does not provide -V
by default, so Ben's solution is as close as it gets. For your convenience I post here our version that is able to sort files like <label>-<version>.<ext>
:
% ls bla-*.ime | sed -Ee 's/^(.*-)([0-9.]+)(\.ime)$/\2.-1 \1\2\3/' | sort -t. -n -k1,1 -k2,2 -k3,3 -k4,4 | cut -d\ -f2-
bla-1.ime
bla-1.0.ime
bla-1.0.0.ime
bla-1.1.ime
bla-1.1.29.ime
bla-1.2.3.ime
bla-1.2.29.ime
bla-1.2.30.ime
bla-1.3.ime
bla-1.3.0.ime
bla-1.3.1.ime
bla-1.3.10.ime
bla-1.3.20.ime
bla-1.7.ime
bla-1.11.29.ime
bla-2.3.2.ime
bla-11.2.2.ime
Short explanation:
- List the files that you want to sort with
ls
. - Find the version number and prefix the line with that.
- While doing that add
-1
to the end to make shorter version number sort first (before.0
even). You could change-1
to0
if you consider1.3
to be equivalent to1.3.0
. - Sort the lines using Ben's suggested solution on the version number.
- Chop off the version prefix from the line.
The list now contains a version sorted list of applicable file names. Any additional sorting on the label
part is left as an exercise to the reader.