Con GNU sort
, y un shell donde printf
está incorporado (todos los POSIX como hoy en día excepto algunas variantes de pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Ahora, un problema con eso es que debido a que los dos componentes de esa tubería se ejecutan de manera simultánea e independiente, cuando el izquierdo expande el *
globo, el derecho ya puede haber creado el output
archivo, lo que podría causar un problema (tal vez no -u
aquí) como output
sería un archivo de entrada y de salida, por lo que es posible que desee que la salida vaya a otro directorio ( > ../output
por ejemplo), o asegúrese de que el glob no coincida con el archivo de salida.
Otra forma de abordarlo en este caso es escribirlo:
printf '%s\0' * | sort -u --files0-from=- -o output
De esa manera, se sort
abre output
para escribir y (en mis pruebas), no lo hará antes de que haya recibido la lista completa de archivos (tanto tiempo después de que el globo se haya expandido). También evitará el clobbering output
si ninguno de los archivos de entrada es legible.
Otra forma de escribirlo con zsh
obash
sort -u --files0-from=<(printf '%s\0' *) -o output
Eso está usando la sustitución del proceso (donde <(...)
se reemplaza por una ruta de archivo que se refiere al final de la lectura en la que printf
se escribe la tubería ). Esa característica proviene ksh
, pero ksh
insiste en hacer la expansión de <(...)
un argumento separado para el comando para que no pueda usarlo con la --option=<(...)
sintaxis. Sin embargo, funcionaría con esta sintaxis:
sort -u --files0-from <(printf '%s\0' *) -o output
Tenga en cuenta que verá una diferencia con respecto a los enfoques que alimentan la salida de cat
los archivos en los casos en que hay archivos que no terminan en un carácter de nueva línea:
$ 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
También tenga en cuenta que sort
ordena usando el algoritmo de intercalación en el locale ( strcollate()
), e sort -u
informa uno de cada conjunto de líneas que se clasifican de la misma manera por ese algoritmo, no líneas únicas a nivel de byte. Si solo le importa que las líneas sean únicas a nivel de byte y no le importe tanto el orden en que están ordenadas, es posible que desee fijar la configuración regional en C donde la ordenación se basa en valores de bytes ( memcmp()
; eso probablemente aceleraría cosas significativamente):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sort
lo hace automáticamente para la entrada de múltiples archivos ... pero luegosort -u *
también fallaríaArgument list too long
, supongo