it-swarm.com.de

Listendateien numerisch sortiert

Ich habe eine Reihe von Dateien von log1 bis log164.

Ich versuche, das Verzeichnis (sortiert) in einem UNIX-Terminal aufzulisten, aber die Sortierfunktionen bieten nur das folgende Format:

home:logs Home$ ls -1 | sort
log1.gz
log10.gz
log100.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz
...etc

Was ich will ist

home:logs Home$ ls -1 | sort
log1.gz
log2.gz
log3.gz
log4.gz
log5.gz
log6.gz
log7.gz
...{more here}
log99.gz
log100.gz
log101.gz
log102.gz
...etc

Irgendwelche Vorschläge, was ich dazu verwenden könnte?

134
Rabiani

bash 's Klammern, {}, zählt sie in der Reihenfolge auf:

for file in log{1..164}.gz; do
    process "$file"
done
40
Kevin

Warum nicht die integrierte Funktion ls für diesen speziellen Fall verwenden:

-v natural sort of (version) numbers within text

Beispielsweise ls -1v log*

293
lik

Mit GNU ls (d. H. Unter Linux, Cygwin oder anderen Systemen, auf denen GNU ls speziell installiert)):

ls -v

In zsh:

echo *(n)

In anderen Schalen:

echo log?.gz log??.gz log???.gz

Ersetzen Sie echo durch printf '%s\n' wenn Sie jeden Dateinamen in einer separaten Zeile haben möchten.

Wenn Sie auch Dateimetadaten möchten (ls -l) und Sie haben nicht GNU ls, Sie müssen ls für jeden Dateinamen oder jede Gruppe von Dateinamen, die Sie in lexikografisch sehen möchten, separat aufrufen Auftrag.

ls -ld log?.gz; ls -ld log??.gz; ls -ld log???.gz

Um diese Schwierigkeiten zu vermeiden, verwenden Sie in Ihren Dateinamen genügend führende Nullen, damit die lexikografische Sortierung für den Menschen geeignet ist (log001.gz, usw).

Während die Lösung ls -1v In diesem speziellen Fall sicherlich die schönste ist, finde ich es gut, auch eine zu haben, die mit sort wie in der ursprünglichen Frage funktioniert, da dies auch funktioniert, wenn Ihre Eingabe dies nicht tut kommen von ls. In diesem Fall können Sie verwenden:

ls -1 | sort -n -k1.4

Die Option -n Weist sort an, numerisch zu sortieren, und -k 1.4 Setzt den Sortierschlüssel auf das erste Feld (in diesem Fall den gesamten Dateinamen), beginnend mit dem 4. bis zum letzten Zeichen.

29
Elmar Zander

Das GNU sort (wie unter Linux verfügbar) verfügt über einen "Versionssortiermodus", der Zahlen in Nicht-Zahlen genau so interpretiert, wie Sie es wünschen:

Von man 1 sort:

    -V, --version-sort
           natural sort of (version) numbers within text

(Erstellen leerer Testdateien zur Liste:
touch log1.gz log2.gz log3.gz log99.gz log100.gz log101.gz log102.gz)

Ihr Beispielfall, das Hinzufügen des -V Option (oder --version-sort):

ls -1 log*.gz | sort -V
log1.gz
log2.gz
log3.gz
log99.gz
log100.gz
log101.gz
log102.gz
24
Volker Siegel

wenn Sie Mac oder BSD verwenden, versuchen Sie Folgendes:

ls -1 *.jpg | sort -n
8

Meine Version von Solaris unterstützt ls -v (Grrr) nicht. Und die oben bereitgestellte Sortierlösung 1) erfordert die Kenntnis der Position der Ziffern im Dateinamen und 2) behandelt keine Dinge wie mehrteilige Versionsnummern.

Der folgende Ansatz ist Solaris-kompatibel, erfordert keine vorherige Kenntnis der Ziffernpositionen und verarbeitet Versionsnummern mit 2, 3 oder 4 Komponenten (wie: a-1.2, foo-5.6.7, bar_baz_9.10.11.12). Es verwendet auch sort -f, Um Groß- und Kleinbuchstaben zusammenzufalten, und behandelt Verzeichnisse, die mit Dateien vermischt sind, ordnungsgemäß:

ls -d | sort -f -t . -k 1,1 -k 2,2n -k 3,3n -k 4,4n

Beachten Sie, dass diese Version die erste Komponente auf eine einzelne Ziffer beschränkt.

Wenn Ihre Zielbetriebssysteme ls -v Unterstützen, ist dies eindeutig die überlegene Lösung.

3
MykennaC

Perl-Lösung:

ls log*.gz | Perl -ne 'sub getnum{ $_[0] =~ /log(\d+)\.gz/; $1 }; Push @A, $_; END{ print sort { getnum $a <=> $b } @A}'
1
$ ls
log101.gz  log102.gz  log103.gz  log104.gz  log105.gz  log106.gz  log10.gz  log1.gz
$ ls | sort -t . -n -k1.4
log1.gz
log10.gz
log101.gz
log102.gz
log103.gz
log104.gz
log105.gz
log106.gz
1
kjohri

Das hat bei mir funktioniert.

Ich habe Dateien 1.jpg 2.jpg ... 18.jpg

$ echo *.jpg | tr -s ' ' '\n' | sort -n

sort wird wegen nicht druckbarer Farbzeichen mit der Ausgabe von ls verwechselt. Wenn Sie dies versuchen:

ls -1 --color=none *.jpg | sort -n

es wird perfekt funktionieren.

sort kann nicht druckbare Zeichen mit der Option -i ignorieren, aber es funktioniert immer noch nicht und ich weiß nicht warum.

Aber Sie können immer Farbe wie diese abstreifen und sort wird funktionieren:

ls -1 --color=always *.jpg | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" | sort -n

Ich hoffe, dass sort eines Tages eine Option dafür haben wird.

0
cy8g3n