How to loop all files in sorted order in Bash?

for i in `ls *.fas | sort -V`; do some_code; done;

where sort -V does according to man sort a version sort - a natural sort of (version) numbers within text

The same using only ls:

for i in `ls -v *.fas`; do echo $i; done;

You will get the files in ASCII order. This means that vvchr10* comes before vvchr2*. I realise that you can not rename your files (my bioinformatician brain tells me they contain chromosome data, and we simply don't call chromosome 1 "chr01"), so here's another solution (not using sort -V which I can't find on any operating system I'm using):

ls *.fas | sed 's/^\([^0-9]*\)\([0-9]*\)/\1 \2/' | sort -k2,2n | tr -d ' ' |
while read filename; do
  # do work with $filename
done

This is a bit convoluted and will not work with filenames containing spaces.

Another solution: Suppose we'd like to iterate over the files in size-order instead, which might be more appropriate for some bioinformatics tasks:

du *.fas | sort -k2,2n |
while read filesize filename; do
  # do work with $filename
done

To reverse the sorting, just add r after -k2,2n (to get -k2,2nr).


With option sort -g it compares according to general numerical value

 for FILE in `ls ./raw/ | sort -g`; do echo "$FILE"; done

0.log 1.log 2.log ... 10.log 11.log

This will only work if the name of the files are numerical. If they are string you will get them in alphabetical order. E.g.:

 for FILE in `ls ./raw/* | sort -g`; do echo "$FILE"; done

raw/0.log raw/10.log raw/11.log ... raw/2.log