How to simulate "sort -V" on Mac OSX How to simulate "sort -V" on Mac OSX bash bash

How to simulate "sort -V" on Mac OSX


You can download coreUtils from http://rudix.org/packages/index.html . It contains "gnusort" with support "sort -V" sintax


You can use additional features of git tag to get a list of tags matching a pattern and sorted properly for version tag ordering (typically no leading zeros):

$ git tag --sort v:refnamev0.0.0v0.0.1v0.0.2v0.0.3v0.0.4v0.0.5v0.0.6v0.0.7v0.0.8v0.0.9v0.0.10v0.0.11v0.0.12

From $ man git-tag:

   --sort=<type>       Sort in a specific order. Supported type is "refname       (lexicographic order), "version:refname" or "v:refname"        (tag names are treated as versions). Prepend "-" to reverse        sort order. When this option is not given, the sort order       defaults to the value configured for the tag.sort variable       if it exists, or lexicographic order otherwise. See        git config(1).


sed 's/\b\([0-9]\)\b/0\1/g' versions.txt  | sort | sed 's/\b0\([0-9]\)/\1/g'

To explain why this works, consider the first sed command by itself. With your input as versions.txt, the first sed command adds a leading zero onto single-digit version numbers, producing:

06.03.01.0106.03.01.0206.03.01.0306.03.01.1006.03.01.11

The above can be sorted normally. After that, it is a matter of removing the added characters. In the full command, the last sed command removes the leading zeros to produce the final output:

6.3.1.16.3.1.26.3.1.36.3.1.106.3.1.11

The works as long as version numbers are 99 or less. If you have version numbers over 99 but less than 1000, the command gets only slightly more complicated:

sed 's/\b\([0-9]\)\b/00\1/g ; s/\b\([0-9][0-9]\)\b/0\1/g' versions.txt  | sort | sed 's/\b0\+\([0-9]\)/\1/g'

As I don't have a Mac, the above were tested on Linux.

UPDATE: In the comments, Jonathan Leffler says that even though word boundary (\b) is in Mac regex docs, Mac sed doesn't seem to recognize it. He suggests replacing the first sed with:

sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g'

So, the full command might be:

sed 's/^[0-9]\./0&/; s/\.\([0-9]\)$/.0\1/; s/\.\([0-9]\)\./.0\1./g; s/\.\([0-9]\)\./.0\1./g' versions.txt | sort | sed 's/^0// ; s/\.0/./g' 

This handles version numbers up to 99.