Ответ 1
for i in `ls *.fas | sort -V`; do some_code; done;
где sort -V
делает в соответствии с man sort
тип версии - натуральный вид (версии) в тексте
То же самое можно использовать только ls
:
for i in `ls -v *.fas`; do echo $i; done;
Я зацикливаю все файлы в каталоге со следующей командой:
for i in *.fas; do some_code; done;
Однако я получаю такой порядок:
vvchr1.fas
vvchr10.fas
vvchr11.fas
вместо vvchr1.fas, vvchr2.fas, vvchr3.fas, что такое числовой порядок.
Я пробовал команду сортировки, но без успеха.
for i in `ls *.fas | sort -V`; do some_code; done;
где sort -V
делает в соответствии с man sort
тип версии - натуральный вид (версии) в тексте
То же самое можно использовать только ls
:
for i in `ls -v *.fas`; do echo $i; done;
Вы получите файлы в порядке ASCII. Это означает, что vvchr10*
предшествует vvchr2*
. Я понимаю, что вы не можете переименовать свои файлы (мой мозг биоинформатики говорит мне, что они содержат хромосомные данные, и мы просто не называем хромосому 1 "chr01" ), поэтому здесь другое решение (не используя sort -V
, которое я не могу найти на любой операционной системе, которую я использую):
ls *.fas | sed 's/^\([^0-9]*\)\([0-9]*\)/\1 \2/' | sort -k2,2n | tr -d ' ' |
while read filename; do
# do work with $filename
done
Это немного запутанно и не будет работать с именами файлов, содержащими пробелы.
Другое решение. Предположим, мы хотели бы перебирать файлы в порядке размера, что может быть более подходящим для некоторых задач биоинформатики:
du *.fas | sort -k2,2n |
while read filesize filename; do
# do work with $filename
done
Чтобы отменить сортировку, просто добавьте r
после -k2,2n
(чтобы получить -k2,2nr
).
Вы имеете в виду, что файлы с номером 10 поступают перед файлами с номером 3 в вашем списке? То потому что ls
сортирует свой результат очень просто, поэтому something-10.whatever
меньше something-3.whatever
.
Одним из решений является переименование всех файлов, чтобы они имели одинаковое количество цифр (файлы с одной цифрой в них начинаются с 0
в номере).
С опцией sort -g она сравнивается в соответствии с общим числовым значением
for FILE in `ls ./raw/ | sort -g`; do echo "$FILE"; done
0.log 1.log 2.log ... 10.log 11.log
Это будет работать, только если имя файла является числовым. Если они являются строками, вы получите их в алфавитном порядке. Например:.
for FILE in `ls ./raw/* | sort -g`; do echo "$FILE"; done
сырец/0.log сырья /10.log сырья/11.log ... сырой/2.log
Как решение @Kusalananda (возможно, легче запомнить?), но для всех файлов (?):
array=("$(ls |sed 's/[^0-9]*\([0-9]*\)\..*/\1 &/'| sort -n | sed 's/^[^ ]* //')")
for x in "${array[@]}";do echo "$x";done
По существу добавить ключ сортировки, сортировать, удалить ключ сортировки.
EDIT: переместить комментарий в соответствующее решение
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/ //;'
Решает проблему, предполагая, что имя файла остается согласованным, не полагается на очень недавние версии GNU sort
, не полагается на чтение вывода ls
и не становится жертвой канала- к-проблемам.
используйте sort -rh и цикл while
du -sh * | sort -rh | grep -P "avi$" |awk '{print $2}' | while read f; do fp=`pwd`/$f; echo $fp; done;