Avec GNU sort, et un shell où printfest intégré (tous ceux de type POSIX de nos jours sauf quelques variantes de pdksh):
printf '%s\0' * | sort -u --files0-from=- > output
Maintenant, un problème avec cela est que parce que les deux composants de ce pipeline sont exécutés simultanément et indépendamment, au moment où celui de gauche développe le *glob, le droit peut avoir outputdéjà créé le fichier, ce qui pourrait poser problème (peut-être pas avec -uici) comme ce outputserait à la fois un fichier d'entrée et de sortie, vous voudrez peut-être que la sortie aille dans un autre répertoire ( > ../outputpar exemple), ou assurez-vous que le glob ne correspond pas au fichier de sortie.
Une autre façon de le résoudre dans ce cas est de l'écrire:
printf '%s\0' * | sort -u --files0-from=- -o output
De cette façon, il sorts'ouvre outputpour l'écriture et (dans mes tests), il ne le fera pas avant d'avoir reçu la liste complète des fichiers (tant de temps après que le glob ait été développé). Cela évitera également de vous encombrer outputsi aucun des fichiers d'entrée n'est lisible.
Une autre façon de l'écrire avec zshoubash
sort -u --files0-from=<(printf '%s\0' *) -o output
Cela utilise la substitution de processus (où <(...)est remplacé par un chemin de fichier qui se réfère à la fin de lecture du canal d' printfécriture). Cette fonctionnalité vient de ksh, mais kshinsiste pour rendre l'expansion d' <(...)un argument séparé à la commande afin que vous ne puissiez pas l'utiliser avec la --option=<(...)syntaxe. Cela fonctionnerait cependant avec cette syntaxe:
sort -u --files0-from <(printf '%s\0' *) -o output
Notez que vous verrez une différence avec les approches qui alimentent la sortie de catsur les fichiers dans les cas où il y a des fichiers qui ne se terminent pas par un caractère de nouvelle ligne:
$ 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
Notez également que sorttrie en utilisant l'algorithme de classement dans les paramètres régionaux ( strcollate()), et sort -usignale une de chaque ensemble de lignes qui trient la même chose par cet algorithme, pas des lignes uniques au niveau de l'octet. Si vous ne vous souciez que des lignes uniques au niveau de l'octet et ne vous souciez pas tellement de l'ordre dans lequel elles sont triées, vous souhaiterez peut-être fixer les paramètres régionaux à C où le tri est basé sur les valeurs d'octets ( memcmp(); cela accélérerait probablement les choses de manière significative):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sortle fait automatiquement pour plusieurs entrées de fichiers .. maissort -u *échoueraitArgument list too longaussi avec je suppose