10

I have a list of files with a version number at the end that I need to sort

/this/is/a/file/path/product-2.0/file/name/7
/this/is/a/file/path/product-2.0/file/name/10
/this/is/a/file/path/product-2.0/file/name/12
/this/is/a/file/path/product-2.0/file/name/13
/this/is/a/file/path/product-2.0/file/name/6
/this/is/a/file/path/product-2.0/file/name/8
/this/is/a/file/path/product-2.0/file/name/9

when I pipe it through grep it sort like so:

echo $files | sort -n
/this/is/a/file/path/product-2.0/file/name/10
/this/is/a/file/path/product-2.0/file/name/12
/this/is/a/file/path/product-2.0/file/name/13
/this/is/a/file/path/product-2.0/file/name/6
/this/is/a/file/path/product-2.0/file/name/7
/this/is/a/file/path/product-2.0/file/name/8
/this/is/a/file/path/product-2.0/file/name/9

I think the -n is getting confused by the first number in the file name.

How can I sort it numerically by the last number

2
  • Always the same depth of path? Commented Jun 5, 2013 at 16:28
  • yes, but I don't know the depth until I am trying to sort Commented Jun 5, 2013 at 16:32

5 Answers 5

25
Kaizen ~/so_test $ cat ztestfile1 | sort -t'/' -n -k10
/this/is/a/file/path/product-2.0/file/name/6
/this/is/a/file/path/product-2.0/file/name/7
/this/is/a/file/path/product-2.0/file/name/8
/this/is/a/file/path/product-2.0/file/name/9
/this/is/a/file/path/product-2.0/file/name/10
/this/is/a/file/path/product-2.0/file/name/12
/this/is/a/file/path/product-2.0/file/name/13

does this help ?

alternative way ie to be independent from the position .....

 Kaizen ~/so_test  $ cat ztestfile1 | sort -V
 /this/is/a/file/path/product-2.0/file/name/6
 /this/is/a/file/path/product-2.0/file/name/7
 /this/is/a/file/path/product-2.0/file/name/8
 /this/is/a/file/path/product-2.0/file/name/9
 /this/is/a/file/path/product-2.0/file/name/10
 /this/is/a/file/path/product-2.0/file/name/12
 /this/is/a/file/path/product-2.0/file/name/13

please note its a -V (Capital) option in sort that looks into numeric differences in a string to sort ..... like in version number .

man page text ::

   -V, --version-sort
          natural sort of (version) numbers within text
Sign up to request clarification or add additional context in comments.

5 Comments

this is what I had been trying except that I was going by the man page and had extra spaces sort -n -t '/' -k 10 and apparently sort doesn't like that
ohh ok , seems the issue is sorted now ... :)
Be aware that with this kind of solution you have to know and specify the depth of the files.
@michas I am passing the string through tr '/' ' ' | wc -w to determine the depth, it feels there should be a better way, but it works
Me too, The -V, this gives a true sorting when it comes to numbers, the others option groups the lines base on the number of digits in the numbers, which in my book is a faulty sorting :-)
6

You can use / as a column separator:

sort -n -t/ -k 10

Comments

3

Use awk to bring the last field to the front, sort by the 1st field, then apply cut to get rid of the first field. An example using a here document below

awk -F'/' '{print($NF"/"$0)}' <<! | sort -k1n,1n -t'/' | cut -f2- -d'/'
> /this/is/a/file/path/product-2.0/file/name/7
> /this/is/a/file/path/product-2.0/file/name/10
> /this/is/a/file/path/product-2.0/file/name/12
> /this/is/a/file/path/product-2.0/file/name/13
> /this/is/a/file/path/product-2.0/file/name/6
> /this/is/a/file/path/product-2.0/file/name/8
> /this/is/a/file/path/product-2.0/file/name/9
> !
/this/is/a/file/path/product-2.0/file/name/6
/this/is/a/file/path/product-2.0/file/name/7
/this/is/a/file/path/product-2.0/file/name/8
/this/is/a/file/path/product-2.0/file/name/9
/this/is/a/file/path/product-2.0/file/name/10
/this/is/a/file/path/product-2.0/file/name/12
/this/is/a/file/path/product-2.0/file/name/13

Comments

0

Or use a one-liner something like perl or ruby:

ruby -we 'print *readlines.sort_by{|x| File.basename(x).to_i}'

Comments

-1

This gets you sorted by the last item in the path by using / as the field separator, taking the last value and placing it at the start of the line, sorting, then removing the value from the start of the line.

cat data | awk 'BEGIN { FS="/"} { print $(NF) " " $0 }' | sort -n | sed 's/^.*\s//g'

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.