How Can I list files in the same order that flyway executes them in bash?

283 views Asked by At

I have flyway migration scripts, which are named as follows.

V1__description.sql
V2.001__description.sql
V2.002__description.sql
V2__description.sql

The above is the order which they are listed by ls, or the default sort order of find. The order in which they are executed by flyway are

V1__description.sql
V2__description.sql
V2.001__description.sql
V2.002__description.sql

Is there a way to use the bash sort command to list the files in the order in which flyway executes them? The files cannot be renamed.

2

There are 2 answers

0
ghoti On BEST ANSWER

The answer to your question is "No. At least, not by itself."

First off, there is no "bash sort command". The sort command is not actually part of bash, it's a separate tool provided by your operating system. While its usage varies by operating system, no version that I'm aware of would sort your input the way you're asking for.[1] Find out more about its capabilities by running man sort in your shell.

One option might be to stream your file list through something that makes it sortable, then stream it through the reverse conversion after sort:

$ sed 's/^\(V[0-9]\)_/\1.000_/' files.txt | sort -n | sed 's/^\(V[0-9]\)\.000_/\1_/'

[1] I'd love to be corrected on this point.

0
Alfe On

I guess flyway first executes V2__description.sql and then V2.001__*.sql etc. because they are logically to be applied later? Then you can change their names for sorting (and change them back right after sorting):

(
  echo "V1__description.sql"
  echo "V2.001__description.sql"
  echo "V2.002__description.sql"
  echo "V2__description.sql"
) | sed 's/\./_DOT_/g' | sort | sed 's/_DOT_/./g'

This will change all dots to _DOT_ for sorting and change it back again afterwards.

If you have more complex things to accomplish (like the sort order of underscores, dashes, dots and plus signs shall be +_-.) you can change more of them to and fro:

… | sed -e 's/_/_1UNDERSCORE_/g' \
        -e 's/\+/_0PLUS_/g' \
        -e 's/-/_2DASH_/g' \
        -e 's/\./_3DOT_/g' \
  | sort \
  | sed -e 's/_3DOT_/\./g' \
        -e 's/_2DASH_/-/g' \
        -e 's/_0PLUS_/\+/g' \
        -e 's/_1UNDERSCORE_/_/g'

Note that converting the underscore needs to be done first (and reverted last) to not confuse the other converted specially treated characters which are converted later (and reverted earlier).