views:

103

answers:

4

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?

A: 

If you specify to sort that you only want to consider the second field (-k2) don't complain that it does not consider the third one.

In your case, run sort --version-sort without any other argument, maybe this will suit better.

Benoit
It's not the third field (which is "setup" in every case).
Dennis Williamson
Sorry, it *was* the third field, but it was the fact that it was *included* rather than *excluded*. You have to tell `sort` that the key starts *and stops* at field 2 using `-k2,2` to make the OP's command work.
Dennis Williamson
A: 

Looks like this works:

find /data/ -name 'command-*-setup' | sort -t - -k 2,2

not with sort but it works:

tree -ivL 1 /data/ | perl -nlE 'say if /\Acommand-[0-9][0-9a-z.]*-setup\z/'

this doesn't match "command-10-setup.tar" or "my_command-10-setup".

-v: sort the output by version
-i: makes tree not print the indentation lines
-L level: max display depth of the directory tree

sid_com
This fails for `command-10.1-setup`.
Dennis Williamson
A: 

Edit: It turns out that Benoit was sort of on the right track and Roland tipped the balance

You simply need to tell sort to consider only field 2 (add ",2"):

find ... | sort --version-sort --field-separator=- --key=2,2

Original Answer: ignore

If none of your filenames contain spaces between the hyphens, you can try this:

find ... | sed 's/.*-\([^-]*\)-.*/\1 \0/;s/[^0-9] /.&/' | sort --version-sort --field-separator=- --key=2 | sed 's/[^ ]* //'

The first sed command makes the lines look like this (I added "10" to show that the sort is numeric):

1.9.a command-1.9a-setup
2.0.c command-2.0c-setup
2.0.a command-2.0a-setup
2.0 command-2.0-setup
10 command-10-setup

The extra dot makes the letter suffixed version number sort after the version number without the suffix. The second sed command removes the prefixed version number from each line.

There are lots of ways this can fail.

Dennis Williamson
When I try only with this part I get the right order: find /home/mm/ztest/ -name 'truecrypt-*-setup' | sed 's/.*-\([^-]*\)-.*/\1 \0/;s/[^0-9] /.
sid_com
@sid_com: Oops, see my edit.
Dennis Williamson
This fails for command-10-setup.
sid_com
@sid_com: Which fails for `command-10-setup`? They both work for me. What is your `locale`? What version of `sort` do you have?
Dennis Williamson
With this sort-setup the command-10-setup is in the first output-row. locale: de_DE.UTF-8. sort (GNU coreutils) 7.1
sid_com
@sid_com: When I set `LC_COLLATE=de_DE.utf8` and do the sort using GNU coreutils 7.4, `command-10-setup` is the last line (using `sort --version-sort --field-separator=- --key=2,2`).
Dennis Williamson
A: 
$ cat files
command-1.9a-setup
command-2.0c-setup
command-10.1-setup
command-2.0a-setup
command-2.0-setup

$ cat files | sort -t- -k2,2 -n
command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup
command-10.1-setup

$ tac files | sort -t- -k2,2 -n
command-1.9a-setup
command-2.0-setup
command-2.0a-setup
command-2.0c-setup
command-10.1-setup
Roland Illig
I don't get the same sorting with your sort-options.
sid_com
@Roland: What locale are you using? I don't get that order either.
Dennis Williamson
I'm using `CYGWIN_NT-5.1 bacc 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin` and no special locale, so it should be the same as locale `C`.
Roland Illig