Search code examples
bashnatural-sort

How to loop over files in natural order in Bash?


I am looping over all the files in a directory with the following command:

for i in *.fas; do some_code; done;

However, I get them in this order

vvchr1.fas  
vvchr10.fas  
vvchr11.fas
vvchr2.fas
...

instead of

vvchr1.fas
vvchr2.fas
vvchr3.fas
...

what is natural order.

I have tried sort command, but to no avail.


Solution

  • readarray -d '' entries < <(printf '%s\0' *.fas | sort -zV)
    for entry in "${entries[@]}"; do
      # do something with $entry
    done
    

    where printf '%s\0' *.fas yields a NUL separated list of directory entries with the extension .fas, and sort -zV sorts them in natural order.

    Note that you need GNU sort installed in order for this to work.