Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unix sort of version numbers

Tags:

unix

sorting

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.

like image 399
Ben Avatar asked Dec 20 '10 19:12

Ben


People also ask

How do you sort numbers in Unix?

-k Option: Unix provides the feature of sorting a table on the basis of any column number by using -k option. Use the -k option to sort on a certain column. For example, use “-k 2” to sort on the second column.

What is sort version?

Version sort puts items such as file names and lines of text in an order that feels natural to people, when the text contains a mixture of letters and digits.

What is Unix sort?

The sort command sorts the contents of a file, in numeric or alphabetic order, and prints the results to standard output (usually the terminal screen). The original file is unaffected. The output of the sort command will then be stored in a file named newfilename in the current directory.


3 Answers

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
like image 53
Ben Avatar answered Oct 17 '22 13:10

Ben


sort -V versions.txt

From man sort:

-V, --version-sort
natural sort of (version) numbers within text

See also Details about version sort.

like image 22
Pikrass Avatar answered Oct 17 '22 11:10

Pikrass


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 to 0 if you consider 1.3 to be equivalent to 1.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.

like image 37
Coroos Avatar answered Oct 17 '22 12:10

Coroos