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):