Com o GNU sort
, e um shell em que printf
está embutido (todos os similares ao POSIX atualmente, exceto algumas variantes de pdksh
):
printf '%s\0' * | sort -u --files0-from=- > output
Agora, um problema com isso é que, como os dois componentes desse pipeline são executados simultaneamente e de forma independente, no momento em que o esquerdo expande o *
globo, o direito pode já ter criado o output
arquivo, o que poderia causar problemas (talvez não -u
aqui) como output
seria um arquivo de entrada e saída, você pode querer que a saída vá para outro diretório ( > ../output
por exemplo) ou verifique se o glob não corresponde ao arquivo de saída.
Outra maneira de resolvê-lo neste caso é escrevê-lo:
printf '%s\0' * | sort -u --files0-from=- -o output
Dessa forma, está sort
abrindo output
para gravação e (nos meus testes), não o fará antes de receber a lista completa de arquivos (muito tempo depois que a glob foi expandida). Também evitará estroboscópios output
se nenhum dos arquivos de entrada for legível.
Outra maneira de escrevê-lo com zsh
oubash
sort -u --files0-from=<(printf '%s\0' *) -o output
Isso está usando substituição de processo (onde <(...)
é substituído por um caminho de arquivo que se refere ao final de leitura do pipe no qual printf
está sendo gravado). Esse recurso vem ksh
, mas ksh
insiste em fazer a expansão de <(...)
um argumento separado para o comando, para que você não possa usá-lo com a --option=<(...)
sintaxe. Porém, ele funcionaria com esta sintaxe:
sort -u --files0-from <(printf '%s\0' *) -o output
Observe que você verá uma diferença das abordagens que alimentam a saída dos cat
arquivos nos casos em que existem arquivos que não terminam com um caractere de nova linha:
$ 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
Observe também que sort
classifica usando o algoritmo de intercalação no locale ( strcollate()
) e sort -u
relata um de cada conjunto de linhas que são iguais por esse algoritmo, não linhas únicas no nível de bytes. Se você se preocupa apenas com as linhas serem únicas no nível de bytes e não se importa muito com a ordem em que elas são classificadas, convém fixar o código do idioma em C, onde a classificação se baseia nos valores de bytes ( memcmp()
; isso provavelmente aceleraria coisas significativamente):
printf '%s\0' * | LC_ALL=C sort -u --files0-from=- -o output
sort
ele automaticamente para a entrada de vários arquivos .. mas, em seguida,sort -u *
iria falhar comArgument list too long
bem suponho