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?

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

  • 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. – Stéphane Chazelas Aug 24 '17 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 – Stéphane Chazelas Aug 24 '17 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. – Egor Vasilyev Aug 24 '17 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....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.