How to loop all files in sorted order in Bash?

后端 未结 7 1042
离开以前
离开以前 2020-12-05 01:51

I am looping all files in directory with following command:

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

However, I get order like this:

<         


        
相关标签:
7条回答
  • 2020-12-05 02:20
    while IFS= read -r  file ; do
        ls -l "$file" # or whatever
    done < <(find . -name '*.fas' 2>/dev/null | sed -r -e 's/([0-9]+)/ \1/' | sort -k 2 -n | sed -e 's/ //;'
    

    Solves the problem, presuming the file naming stays consistent, doesn't rely on very-recent versions of GNU sort, does not rely on reading the output of ls and doesn't fall victim to the pipe-to-while problems.

    0 讨论(0)
  • 2020-12-05 02:24

    use sort -rh and the while loop

    du -sh * | sort -rh | grep -P "avi$" |awk '{print $2}' | while read f; do fp=`pwd`/$f; echo $fp; done;
    
    0 讨论(0)
  • 2020-12-05 02:33

    Like @Kusalananda's solution (perhaps easier to remember?) but catering for all files(?):

    array=("$(ls |sed 's/[^0-9]*\([0-9]*\)\..*/\1 &/'| sort -n | sed 's/^[^ ]* //')")
    for x in "${array[@]}";do echo "$x";done
    

    In essence add a sort key, sort, remove sort key.

    EDIT: moved comment to appropriate solution

    0 讨论(0)
  • 2020-12-05 02:34

    You mean that files with the number 10 comes before files with number 3 in your list? Thats because ls sorts its result very simple, so something-10.whatever is smaller than something-3.whatever.

    One solution is to rename all files so they have the same number of digits (the files with single-digit in them start with 0 in the number).

    0 讨论(0)
  • 2020-12-05 02:36

    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).

    0 讨论(0)
  • 2020-12-05 02:37
    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;
    
    0 讨论(0)
提交回复
热议问题