Home > OS >  BASH sorting file names by version
BASH sorting file names by version

Time:10-22

I need to order these file names (and I can't change them):

  • file_31_stable.sql
  • file_32_stable.sql
  • file_310_stable.sql
  • file_41_stable.sql
  • file_42_stable.sql
  • file_410_stable.sql

This is also the expected order that I want to display them, because I have to get the last one.

When I use the command

find ./databases/ -iname file_*.sql | sort -V

The output is this:

file_31_stable.sql
file_32_stable.sql
file_41_stable.sql
file_42_stable.sql
file_310_stable.sql
file_410_stable.sql

There is a form to order using the first number of the file and then the rest, or a command that will display the expected order?

CodePudding user response:

Without any separators, version 310 is obviously newer than version 41.

If you can devise a way to automatically add a separator, of course do that. Maybe

find ./databases/ -iname 'file_*.sql' |
sed 's/^\([^_]*_\)\([0-9]\)\([0-9]*\)/\2.\3\t\1\2\3/' |
sort -k1 -V |
cut -f2-

if you know the major version must always be a single digit; but obviously, in the general case, no such assumptions can be made.

This adds a column before the actual value, sorts on that, and then peels off the added column; see also Schwartzian transform. Before the cut, the output from sort looks like

3.1     file_31_stable.sql
3.2     file_32_stable.sql
3.10    file_310_stable.sql
4.1     file_41_stable.sql
4.2     file_42_stable.sql
4.10    file_410_stable.sql

If your sed does not recognize \t as a tab, maybe try putting a literal tab (I can't do that here because Stack Overflow renders tabs as spaces).

  • Related