Ich habe ein Verzeichnis voller Dateien mit Namen, bei logXX
denen XX eine zweistellige, mit Nullen aufgefüllte Hex-Zahl in Großbuchstaben ist, wie zum Beispiel:
log00
log01
log02
...
log0A
log0B
log0C
...
log4E
log4F
log50
...
Im Allgemeinen gibt es weniger als 20 oder 30 Dateien insgesamt. Das Datum und die Uhrzeit auf meinem bestimmten System können nicht als zuverlässig angesehen werden (ein eingebettetes System ohne zuverlässige NTP- oder GPS-Zeitquellen). Die Dateinamen werden jedoch wie oben gezeigt zuverlässig erhöht.
Ich wollte grep
alle Dateien für den letzten einzelnen Protokolleintrag eines bestimmten Typs durchgehen, ich hatte gehofft, cat
die Dateien zusammen wie ...
cat /tmp/logs/log* | grep 'WARNING 07 -' | tail -n1
Mir ist jedoch aufgefallen, dass verschiedene Versionen von bash
oder sh
oder zsh
usw. unterschiedliche Vorstellungen darüber haben, wie das *
erweitert wird.
Die man bash
Seite sagt nicht aus, ob die Erweiterung von *
eine definitiv aufsteigende alphabetische Liste passender Dateinamen wäre oder nicht . Es scheint jedes Mal aufzusteigen, wenn ich es auf allen mir zur Verfügung stehenden Systemen ausprobiert habe - aber ist es DEFINIERTES Verhalten oder nur implementierungsspezifisch?
Mit anderen Worten, kann ich mich absolut darauf verlassen cat /tmp/logs/log*
, dass alle meine Protokolldateien in alphabetischer Reihenfolge zusammengefügt werden?
sort
ist dieselbe wie für die Shell, wenn ein Dateinamen-Globbing-Muster erweitert wird.cat
mitgrep -h pattern /tmp/logs/log*
Voranstellen von Dateinamen zu den Spielen zu unterdrücken. (Zumindest mit GNU grep habe ich POSIX oder busybox nicht überprüft.)cat
, dies ist nutzlos vonsort
Antworten:
In allen Shells werden Globs standardmäßig sortiert. Sie wurden bereits von dem
/etc/glob
Helfer von Ken Thompsons Shell aufgerufen, um Globs in der ersten Version von Unix in den frühen 70ern zu erweitern (und die Globs ihren Namen gaben).Für
sh
POSIX ist es erforderlichstrcoll()
, dass die Sortierung anhand der Sortierreihenfolge im Gebietsschema des Benutzers erfolgt, wie dies beils
einigen noch immer der Fallstrcmp()
ist und nur auf Byte-Werten basiert.Sie werden vielleicht bemerken, dass für die Shells, die nach dem Gebietsschema sortieren, hier auf einem GNU-System mit einem
en_GB.UTF-8
Gebietsschema, der-
in den Dateinamen für die Sortierung ignoriert wird (die meisten Interpunktionszeichen würden). Dieó
Sortierung erfolgt erwartungsgemäßer (zumindest für die Briten), und die Groß- und Kleinschreibung wird ignoriert (außer wenn es um die Entscheidung über eine Bindung geht).Sie werden jedoch einige Inkonsistenzen für log① log② feststellen. Das liegt daran, dass die Sortierreihenfolge von ① und ② nicht in GNU-Gebietsschemata definiert ist (derzeit; hoffentlich wird sie eines Tages behoben). Sie sortieren gleich, so dass Sie zufällige Ergebnisse erhalten.
Das Ändern des Gebietsschemas wirkt sich auf die Sortierreihenfolge aus. Sie können das Gebietsschema auf C setzen, um eine
strcmp()
ähnliche Sortierung zu erhalten:Beachten Sie, dass einige Gebietsschemas auch für reine ASCII-Zeichenfolgen zu Verwirrungen führen können. Wie die tschechischen (zumindest auf GNU-Systemen), wo
ch
sich ein Sortierelement befindet, das nach Folgendem sortierth
:Oder, wie von @ninjalj hervorgehoben, noch seltsamere in ungarischen Gegenden:
In
zsh
können Sie die Sortierung mit Glob-Qualifiern wählen . Zum Beispiel:Die numerische Sortierung
echo *(n)
kann auch global mit dernumericglobsort
Option aktiviert werden :Wenn Sie (wie ich) in diesem speziellen Fall (hier unter Verwendung meines britischen Gebietsschemas) durch diese Anweisung verwirrt sind, finden Sie hier weitere Informationen.
quelle
&C<cs<<<Cs<<<CS
, während&C<cs<<<cS<<<Cs<<<CS
als vorgeschlagener Versuchsentwurf gekennzeichnet ist. Nach einigen älteren Daten zu urteilen, die in CLDR importiert wurden, schienen ältere AIX- und MS-Systeme die Ansicht "Kleinbuchstaben sind 2 verschiedene Sortierelemente" vorzuziehen.Die Manpage für bash gibt Folgendes an:
quelle
man
beim Rendern von Text gefunden ... Wenn der gesuchte Text "umbrochen" wird, wird er von einem / search-Befehl nicht gefunden. Nur mein Terminal maximiert und da ist es :)bash
. Das OP interessierte sich auch für "zsh etc."Sofern Sie in einigen Shells nicht bestimmte Shell-Optionen auslösen, ist die Ausgabe garantiert gleich.
Die Bestellung ist im POSIX-Standard festgelegt :
Siehe auch LC_COLLATE-Kategorie im POSIX-Gebietsschema , in dem kurz gesagt steht, dass wenn
LC_COLLATE=C
, die Dinge in ASCII-Reihenfolge sortiert sind.Das
bash
Handbuch erwähntksh93
undzsh
hat einen ähnlichen Wortlaut, der mich zu der Annahme veranlasst, dass sie in dieser Hinsicht dem POSIX-Standard folgen.Andere Shells mögen
pdksh
unddash
sagen nichts über die Sortierung der Dateinamen aus, die sich aus dem Verschieben von Dateinamen ergeben. Ich bin versucht zu glauben, dass dies bedeutet, dass sie immer noch denselben Standard einhalten, zumindest wenn sie das POSIX-Gebietsschema verwenden. Meiner Erfahrung nach bin ich nicht auf eine Shell gestoßen, die ASCII-Dateinamen "seltsam" sortiert.quelle
numericglobsort
Option anzsh
, die die Sortierung beeinflussen würde. Obwohl ich es vorziehen würde,echo *(n)
die Option global zu aktivieren, anstatt sie global zu aktivieren .--posix
Befehlszeilenoption aufrufen oder "set -o posix
posix
Modus nicht beeinflusst . Siehe gnu.org/software/bash/manual/html_node/Bash-POSIX-Mode.html Dies lässt mich glauben (hoffentlich), dass die Sortierung POSIX-kompatibel ist.Wenn das primäre Ziel darin besteht, Eingabedateien nach ihrem Alter zu sortieren, das älteste zuerst, können Sie schreiben
Und wenn es sich auch um gedrehte und komprimierte Protokolle handelt:
quelle