GNU comm
(a partir do GNU coreutils 8.25) agora tem uma opção -z
/ --zero-terminated
para isso.
Para versões anteriores do GNU comm
, você deve ser capaz de trocar NUL e NL:
comm -13 <(cd dir1 && find . -type f -print0 | tr '\n$ touch dir1/{①,②} dir2/{②,③}
$ comm -12 <(cd dir1 && find . -type f -print0 | tr '\ncomm -13 <(cd dir1 && find . -type f -print0 | tr '\n$ touch dir1/{①,②} dir2/{②,③}
$ comm -12 <(cd dir1 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort)
./③
./②
$ (export LC_ALL=C
comm -12 <(cd dir1 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort))
./②
' '%pre%\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort) |
tr '\n%pre%' '%pre%\n'
' '%pre%\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort)
./③
./②
$ (export LC_ALL=C
comm -12 <(cd dir1 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort))
./②
' '%pre%\n' | sort) \
<(cd dir2 && find . -type f -print0 | tr '\n%pre%' '%pre%\n' | sort) |
tr '\n%pre%' '%pre%\n'
Dessa forma, comm
ainda funciona com registros delimitados por novas linhas, mas com novas linhas reais na entrada codificadas como NULs, portanto, ainda estamos seguros com nomes de arquivos contendo novas linhas.
Você também pode querer definir a localidade como C
, porque nos sistemas GNU e na maioria das localidades UTF-8 existem pelo menos cadeias de caracteres diferentes que ordenam o mesmo e causariam problemas aqui.
Esse é um truque muito comum (veja Inverta linhas correspondentes, separadas por NUL para outro exemplo com comm
), mas precisa de utilitários que suportem o NUL em sua entrada, que fora dos sistemas GNU é relativamente raro.
¹ Exemplo:
%pre%