Ich schleife alle Dateien im Verzeichnis mit folgendem Befehl:
for i in *.fas; do some_code; done;
Ich bekomme aber so Ordnung:
vvchr1.fas
vvchr10.fas
vvchr11.fas
anstelle von vvchr1.fas, vvchr2.fas, vvchr3.fas ist die numerische Reihenfolge.
Ich habe Sortierbefehl versucht, aber ohne Erfolg.
for i in `ls *.fas | sort -V`; do some_code; done;
wo sort -V
nach man sort
eine Versionssortierung durchführt - eine natürliche Art von (Versions-) Zahlen im Text
Dasselbe, wenn nur ls
verwendet wird:
for i in `ls -v *.fas`; do echo $i; done;
Sie erhalten die Dateien in der Reihenfolge ASCII. Dies bedeutet, dass vvchr10*
vor vvchr2*
steht. Ich weiß, dass Sie Ihre Dateien nicht umbenennen können (mein bioinformatisches Gehirn sagt mir, dass sie Chromosomendaten enthalten, und wir nennen Chromosom 1 einfach nicht "chr01"). Hier ist eine andere Lösung (sort -V
, die ich auf keiner finden kann) Betriebssystem, das ich verwende):
ls *.fas | sed 's/^\([^0-9]*\)\([0-9]*\)/\1 \2/' | sort -k2,2n | tr -d ' ' |
while read filename; do
# do work with $filename
done
Dies ist ein wenig kompliziert und funktioniert nicht mit Dateinamen, die Leerzeichen enthalten.
Eine andere Lösung: Nehmen wir an, wir möchten die Dateien stattdessen in der Reihenfolge ihrer Größe durchlaufen, was für einige Bioinformatik-Aufgaben besser geeignet ist:
du *.fas | sort -k2,2n |
while read filesize filename; do
# do work with $filename
done
Um die Sortierung umzukehren, fügen Sie einfach r
nach -k2,2n
hinzu (um -k2,2nr
zu erhalten).
Mit der Option sort -g wird der allgemeine numerische Wert verglichen
for FILE in `ls ./raw/ | sort -g`; do echo "$FILE"; done
0.log 1.log 2.log ... 10.log 11.log
Dies funktioniert nur, wenn der Name der Dateien numerisch ist. Wenn sie eine Zeichenfolge sind, werden sie in alphabetischer Reihenfolge angezeigt. Z.B.:
for FILE in `ls ./raw/* | sort -g`; do echo "$FILE"; done
raw/0.log raw/10.log raw/11.log ... raw/2.log
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/ //;'
Behebt das Problem, unter der Annahme, dass die Dateinamen konsistent bleiben, nicht auf sehr aktuelle Versionen von GNU sort
angewiesen ist, nicht auf das Lesen der Ausgabe von ls
angewiesen ist und nicht der Pipeline zum Opfer fällt Probleme.
Sie meinen, dass Dateien mit der Nummer 10 vor Dateien mit der Nummer 3 in Ihrer Liste stehen? Das ist, weil ls
sein Ergebnis sehr einfach sortiert, so dass something-10.whatever
kleiner als something-3.whatever
ist.
Eine Lösung besteht darin, alle Dateien so umzubenennen, dass sie die gleiche Anzahl von Ziffern haben (die Dateien mit einstelligen Ziffern beginnen mit 0
in der Anzahl).
Wie @ Kusalanandas Lösung (vielleicht einfacher zu merken?), Aber für alle Dateien (?):
array=("$(ls |sed 's/[^0-9]*\([0-9]*\)\..*/\1 &/'| sort -n | sed 's/^[^ ]* //')")
for x in "${array[@]}";do echo "$x";done
Im Wesentlichen einen Sortierschlüssel hinzufügen, sortieren, Sortierschlüssel entfernen.
BEARBEITEN: Kommentar in die entsprechende Lösung verschoben
verwenden Sie sort -rh und die while-Schleife
du -sh * | sort -rh | grep -P "avi$" |awk '{print $2}' | while read f; do fp=`pwd`/$f; echo $fp; done;