6

I am trying to sort file names in a directory as below.

$ ls -1v
file-1.10.0-114.1.1.x86.tb1_2.rpm  
file-1.10.0-114.2.2.x86.tb1_2.rpm  
file-1.10.0-114.11.2.x86.tb1_2.rpm  
file-1.10.0-114.x86.tb1_2.rpm  
file-1.10.0-115.1.1.x86.tb1_2.rpm  
file-1.10.0-115.2.2.x86.tb1_2.rpm  
file-1.10.0-115.3.1.x86.tb1_2.rpm  
file-1.10.0-115.22.1.x86.tb1_2.rpm  
file-1.10.0-115.x86.tb1_2.rpm  

But, my expectation was the below.

file-1.10.0-114.x86.tb1_2.rpm  
file-1.10.0-114.1.1.x86.tb1_2.rpm  
file-1.10.0-114.2.2.x86.tb1_2.rpm  
file-1.10.0-114.11.2.x86.tb1_2.rpm  
file-1.10.0-115.x86.tb1_2.rpm  
file-1.10.0-115.1.1.x86.tb1_2.rpm  
file-1.10.0-115.2.2.x86.tb1_2.rpm  
file-1.10.0-115.3.1.x86.tb1_2.rpm  
file-1.10.0-115.22.1.x86.tb1_2.rpm

I tried sort -V, but it showed the same result. How do I sort like this way?

4

2 Answers 2

12

Try to use this command:

ls -h | sort -t. -k3,3 -k4,4n

ls -h - standard output of ls command (you can use ls -lh with the same result provided the user and group names don't contain dots);

-t. - setting up the separator for sort command;

-k3,3 - sorting by third field

and after this ...

-k4,4n - sorting by fourth field numerically

3
  • but that would sort a file-1.10.0-93.11.2.x86.tb1_2.rpm after file-1.10.0-115.22.1.x86.tb1_2.rpm as the sort on the 3rd field is not numerical. Aug 24, 2017 at 14:21
  • That would also sort file-1.10.0-115.1.10.x86.tb1_2.rpm before file-1.10.0-115.1.2.x86.tb1_2.rpm Aug 24, 2017 at 14:28
  • Thanks for the comments. You are absolutely right. These exceptions will not be handled correctly. But if the values are between 0-100 and 0-999 just like in the author's example, everything will be fine. Aug 24, 2017 at 16:00
2

With zsh, you can do:

print -rl file*.rpm(noe:'REPLY=${REPLY%.x*}':)

That is do a numeric (n) sort on the file name stripped of the trailing .x* part.

You can do something similar with GNU sort with:

ls | sort -Vtx -k 1,1

assuming there's no x anywhere else, though that one would have issues with file names containing newline characters.

Or you could do:

print -rl file*.rpm(noe:'REPLY=${REPLY//(#m)<->/Z$MATCH}':)

(with extendedglob) where we prefix every number with Z so the Z115.xZ86... sorts before the Z115.Z1....

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .