Listet Dateien numerisch sortiert auf

123

Ich habe ein paar Dateien von log1bis 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 gebrauchen könnte?

Volker Siegel
quelle
8
Dies ist absolut eine Programmierfrage und verdient es nicht, migriert zu werden, nur weil die Antwort die Programmiersprache Low-Shell beinhaltet !!!
Christ
Wenn Sie im Voraus wissen, dass sie log1.gzdurch benannt sind log164.gz, wofür brauchen Sie ls -1sie dann überhaupt?
Ruakh
1
@ruakh ls -1 zeigt die Ergebnisse in einer Spalte und nicht in der anderen an
3
@Rabiani: Ich weiß was es ls -1tut: es listet Dateinamen auf. Da Sie die Dateinamen bereits kannten, habe ich nicht verstanden, wofür Sie sie brauchten. Aber da Sie Kevins Antwort akzeptiert haben, weiß ich jetzt: Sie haben sie nicht gebraucht. Welches macht mehr Sinn. :-)
ruakh

Antworten:

40

bash's geschweifte Klammern {}werden sie in der folgenden Reihenfolge auflisten:

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

Warum nicht die integrierte lsFunktion für diesen speziellen Fall verwenden, nämlich

-v natural sort of (version) numbers within text

Zum Beispiel ls -1v log*

lik
quelle
Tolle Lösung, obwohl ich mir wünschte, es gäbe eine ebenso einfache Lösung sortfür den Fall, dass man eine Reihe von Zeichenfolgen anstelle eines Verzeichnisses von Dateien hat
Hubro
23
Auf BSD / OS X ist diese Option noch etwas anderes: -v - Force unedited printing of non-graphic characters.
Kenorb
Leider ist die Option -v unter AIX (6.1)
bouvierr
6
Dies sollte die beste Antwort sein.
32r34wgf3e
1
Für MacOS wird dies funktionieren, ich konnte nur die oben genannte Option nicht findenls | sort -n
Ricky Levi
47

Mit GNU ls (dh unter Linux, Cygwin oder anderen Systemen, auf denen GNU ls speziell installiert ist):

ls -v

In zsh:

echo *(n)

In anderen Schalen:

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

Ersetzen Sie echodurch, printf '%s\n'wenn jeder Dateiname in einer separaten Zeile stehen soll.

Wenn Sie auch Dateimetadaten möchten ( ls -l) und keine GNU ls haben, müssen Sie lsfür jeden Dateinamen oder jede Gruppe von Dateinamen, die Sie in lexikografischer Reihenfolge anzeigen möchten, einen separaten Aufruf durchführen.

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

Um diese Schwierigkeiten zu vermeiden, verwenden Sie in Ihren Dateinamen so viele führende Nullen, dass die lexikografische Sortierung menschlich ist ( log001.gzusw.).

Gilles
quelle
29

Obwohl die Lösung ls -1vin diesem speziellen Fall sicherlich die beste ist, finde ich es gut, auch eine zu haben, die sortwie in der ursprünglichen Frage funktioniert, da dies auch dann funktioniert, wenn Ihre Eingabe nicht von stammt ls. In diesem Fall können Sie verwenden:

ls -1 | sort -n -k1.4

Die -nOption weist sort an, numerisch zu sortieren, und -k 1.4legt den Sortierschlüssel auf das erste Feld (in diesem Fall den gesamten Dateinamen) vom 4. bis zum letzten Zeichen fest.

Elmar Zander
quelle
In meinem Fall ls -1 | sort -n -k1.4funktioniert das nicht. Es gibt unsortierte zuerst bis zu 4 Zeichen, dann sortierte nach dem 4. Zeichen. Ich habe ls -1 |sort | sort -n -k1.4stattdessen verwendet und es hat perfekt funktioniert.
Prabhu
3
@ Prabhu, stattdessen könnten Sie tun sort -k1.1,1.3 -k1.4n. sortImplementierungen müssen nicht stabil sein, sodass Ihr Ansatz nicht bei allen Implementierungen funktioniert. Siehe auch die -VOption von GNU und FreeBSD sort.
Stéphane Chazelas
21

Die GNU sort(wie sie unter Linux verfügbar ist) verfügt über einen "Versionssortier" -Modus, der Zahlen in Nicht-Zahlen so interpretiert, wie Sie es wünschen:

Von man 1 sort:

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

(Erstellen von leeren Test Dateien aufzulisten:
touch log1.gz log2.gz log3.gz log99.gz log100.gz log101.gz log102.gz)

Ihr Beispielfall, der die -VOption (oder --version-sort) hinzufügt :

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

Wenn Sie einen Mac oder BSD verwenden, versuchen Sie Folgendes:

ls -1 *.jpg | sort -n
Salvador Almaraz
quelle
3

Meine Solaris-Version 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 Vorkenntnisse 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 wird auch verwendet sort -f, um Groß- und Kleinbuchstaben zusammenzufalten und Verzeichnisse, die mit Dateien vermischt sind, richtig zu behandeln:

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 Ihr (e) Zielbetriebssystem (e) dies unterstützt ls -v, ist dies eindeutig die überlegene Lösung.

MykennaC
quelle
1

Perl-Lösung:

ls log*.gz | perl -ne 'sub getnum{ $_[0] =~ /log(\d+)\.gz/; $1 }; push @A, $_; END{ print sort { getnum $a <=> $b } @A}'
Barton Chittenden
quelle
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
kjohri
quelle
1
Das -t .ist hier überflüssig.
Stéphane Chazelas
0

Das hat bei mir funktioniert.

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

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

sortwird lswegen nicht druckbarer Farbzeichen mit der Ausgabe verwechselt . Wenn Sie dies versuchen:

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

es wird perfekt funktionieren.

sortkann nicht druckbare Zeichen mit -iOption ignorieren, aber es funktioniert immer noch nicht und ich weiß nicht warum.

Aber Sie können die Farbe immer so streifen und es sortwird 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 wir eines Tages sorteine Option dafür haben werden.

cy8g3n
quelle