Подтвердить что ты не робот

BASH: как закодировать все файлы в отсортированном порядке

Я зацикливаю все файлы в каталоге со следующей командой:

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

Однако я получаю такой порядок:

vvchr1.fas
vvchr10.fas
vvchr11.fas

вместо vvchr1.fas, vvchr2.fas, vvchr3.fas, что такое числовой порядок.

Я пробовал команду сортировки, но без успеха.

4b9b3361

Ответ 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;

Ответ 2

Вы получите файлы в порядке 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).

Ответ 3

Вы имеете в виду, что файлы с номером 10 поступают перед файлами с номером 3 в вашем списке? То потому что ls сортирует свой результат очень просто, поэтому something-10.whatever меньше something-3.whatever.

Одним из решений является переименование всех файлов, чтобы они имели одинаковое количество цифр (файлы с одной цифрой в них начинаются с 0 в номере).

Ответ 4

С опцией 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

Ответ 5

Как решение @Kusalananda (возможно, легче запомнить?), но для всех файлов (?):

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

По существу добавить ключ сортировки, сортировать, удалить ключ сортировки.

EDIT: переместить комментарий в соответствующее решение

Ответ 6

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 и не становится жертвой канала- к-проблемам.

Ответ 7

используйте sort -rh и цикл while

du -sh * | sort -rh | grep -P "avi$" |awk '{print $2}' | while read f; do fp=`pwd`/$f; echo $fp; done;