Mit GNU sort
und einer printf
eingebauten Shell (alle POSIX-ähnlichen heutzutage mit Ausnahme einiger Varianten von pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Ein Problem dabei ist, dass, da die beiden Komponenten dieser Pipeline gleichzeitig und unabhängig ausgeführt werden, *
die rechte möglicherweise bereits die output
Datei erstellt hat, die Probleme verursachen könnte (möglicherweise nicht -u
hier). output
Da es sich sowohl um eine Eingabe- als auch um eine Ausgabedatei handelt, möchten Sie möglicherweise, dass die Ausgabe in ein anderes Verzeichnis > ../output
verschoben wird ( z. B.), oder stellen Sie sicher, dass der Glob nicht mit der Ausgabedatei übereinstimmt.
Eine andere Möglichkeit, dies in diesem Fall zu beheben, besteht darin, es zu schreiben:
printf '%s\0' * | sort -u --files0-from=- -o output
Auf diese Weise wird es zum Schreiben sort
geöffnet output
und (in meinen Tests) nicht ausgeführt, bevor die vollständige Liste der Dateien empfangen wurde (so lange, nachdem der Glob erweitert wurde). Es wird auch ein Überfallen vermieden, output
wenn keine der Eingabedateien lesbar ist.
Eine andere Möglichkeit, es mit zsh
oder zu schreibenbash
sort -u --files0-from=<(printf '%s\0' *) -o output
Hierbei wird die Prozessersetzung verwendet (wobei <(...)
durch einen Dateipfad ersetzt wird, der sich auf das Leseende bezieht, in das die Pipe printf
schreibt). Diese Funktion stammt von ksh
, ksh
besteht jedoch darauf, <(...)
ein separates Argument für den Befehl zu erweitern, damit Sie es nicht mit der --option=<(...)
Syntax verwenden können. Es würde jedoch mit dieser Syntax funktionieren:
sort -u --files0-from <(printf '%s\0' *) -o output
Beachten Sie, dass Sie einen Unterschied zu Ansätzen cat
feststellen, bei denen die Ausgabe der Dateien in Fällen eingespeist wird, in denen Dateien nicht mit einem Zeilenumbruchzeichen enden:
$ printf a > a
$ printf b > b
$ printf '%s\0' a b | sort -u --files0-from=-
a
b
$ printf '%s\0' a b | xargs -r0 cat | sort -u
ab
Beachten Sie außerdem, dass die sort
Sortierung mithilfe des Kollatierungsalgorithmus in locale ( strcollate()
) erfolgt und sort -u
eine von jedem Satz von Zeilen gemeldet wird, die nach diesem Algorithmus gleich sortiert sind, und keine eindeutigen Zeilen auf Byte-Ebene. Wenn Sie sich nur dafür interessieren, dass Zeilen auf Byte-Ebene eindeutig sind, und sich nicht so sehr für die Reihenfolge interessieren, in der sie sortiert sind, möchten Sie möglicherweise das Gebietsschema auf C festlegen, wobei die Sortierung auf Byte-Werten basiert ( memcmp()
; das würde wahrscheinlich die Geschwindigkeit erhöhen Dinge deutlich):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sort
wird es automatisch für mehrere Dateieingang .. aber dannsort -u *
würde scheitern mitArgument list too long
als auch nehme ich