How can I sort file names by version numbers?

Viewed 19320

In the directory "data" are these files:

command-1.9a-setup
command-2.0a-setup
command-2.0c-setup
command-2.0-setup

I would like to sort the files to get this result:

command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup

I tried this

find /data/ -name 'command-*-setup' | sort --version-sort --field-separator=- -k2 

but the output was

command-1.9a-setup
command-2.0a-setup
command-2.0c-setup
command-2.0-setup

The only way I found that gave me my desired output was

tree -v /data

How could I get with sort the output in the wanted order?

7 Answers

Another way to do this is to pad your numbers.

This example pads all numbers to 8 digits. Then, it does a plain alphanumeric sort. Then, it removes the pad.

$ pad() { perl -pe 's/(\d+)/0000000\1/g' | perl -pe 's/0*(\d{8})/\1/g'; }
$ unpad() { perl -pe 's/0*([1-9]\d*|0)/\1/g'; }
$ cat files | pad | sort | unpad
command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup
command-10.1-setup

To get some insight into how this works, let's look at the padded sorted result:

$ cat files | pad | sort
command-00000001.00000009a-setup
command-00000002.00000000-setup
command-00000002.00000000a-setup
command-00000002.00000000c-setup
command-00000010.00000001-setup

You'll see that with all the numbers nicely padded to 8 digits, the alphanumeric sort puts the filenames into their desired order.

I have files in a folder and need to get those name in sort order, based on the number. E.g. -

abc_dr-1.txt
hg_io-5.txt
kls_er_we-3.txt
sd-4.txt
sl_rt_we_yh-2.txt

I need to sort them based on number. So I used this to sort.

ls -1 | sort -t '-' -nk2

It gave me files in sort order based on number.

Related