Com GNU sort e um shell em que printf está integrado (todos os tipos semelhantes a POSIX atualmente, exceto algumas variantes de pdksh ):
printf '%sprintf '%ssort -u --files0-from=<(printf '%ssort -u --files0-from <(printf '%s$ printf a > a
$ printf b > b
$ printf '%sprintf '%sprintf '%sprintf '%ssort -u --files0-from=<(printf '%ssort -u --files0-from <(printf '%s$ printf a > a
$ printf b > b
$ printf '%sprintf '%s%pre%' * | LC_ALL=C sort -u --files0-from=- -o output
' a b | sort -u --files0-from=-
a
b
$ printf '%s%pre%' a b | xargs -r0 cat | sort -u
ab
' *) -o output
' *) -o output
' * | sort -u --files0-from=- -o output
' * | sort -u --files0-from=- > output
' * | LC_ALL=C sort -u --files0-from=- -o output
' a b | sort -u --files0-from=-
a
b
$ printf '%s%pre%' a b | xargs -r0 cat | sort -u
ab
' *) -o output
' *) -o output
' * | sort -u --files0-from=- -o output
' * | sort -u --files0-from=- > output
Agora, um problema é que, como os dois componentes desse pipeline são executados simultaneamente e de forma independente, no momento em que o esquerdo expande o * glob, o direito pode ter criado o arquivo output já que poderia causar problema (talvez não com -u aqui) como output seria um arquivo de entrada e saída, então você pode querer que a saída vá para outro diretório ( > ../output por exemplo), ou certifique-se de que o glob não corresponde ao arquivo de saída.
Outra maneira de abordá-lo nessa instância é escrevê-lo:
%pre% Dessa forma, é sort opening output para gravação e (em meus testes), não será feito antes de receber a lista completa de arquivos (assim que o glob tiver sido expandido). Ele também evitará a perda de output se nenhum dos arquivos de entrada for legível.
Outra maneira de escrever com zsh ou bash
Isso está usando a substituição de processo (em que <(...) é substituído por um caminho de arquivo que se refere à extremidade de leitura do canal em que printf está gravando). Esse recurso vem de ksh , mas ksh insiste em tornar a expansão de <(...) um argumento separado para o comando, portanto, você não pode usá-lo com a sintaxe --option=<(...) . Funcionaria com esta sintaxe embora:
Note que você verá uma diferença de abordagens que alimentam a saída de cat nos arquivos nos casos em que há arquivos que não terminam em um caractere de nova linha:
Observe também que sort ordena o uso do algoritmo de intercalação na localidade ( strcollate() ) e sort -u informa um de cada conjunto de linhas que classificam o mesmo por esse algoritmo, não linhas exclusivas no nível de byte. Se você se preocupa apenas com o fato de as linhas serem exclusivas em nível de byte e não se importarem tanto com a ordem em que são classificadas, talvez você queira corrigir a localidade para C, onde a classificação é baseada em valores de bytes ( memcmp() ; provavelmente aceleraria as coisas significativamente):