Em resposta a uma pergunta diferente, eu queria usar uma estrutura muito parecida com esta para encontrar arquivos que aparecem em list2
que não aparecem em list1
:
( cd dir1 && find . -type f -print0 ) | sort -z > list1
( cd dir2 && find . -type f -print0 ) | sort -z > list2
comm -13 list1 list2
No entanto, bati em uma parede de tijolos porque minha versão de comm
não pode lidar com registros terminados em NULL. (Alguns antecedentes: estou passando uma lista computada para rm
, então, particularmente, quero ser capaz de lidar com nomes de arquivo que possam conter uma nova linha incorporada.)
Se você quer um exemplo fácil de trabalhar, tente isso
mkdir dir1 dir2
touch dir1/{a,b,c} dir2/{a,c,d}
( cd dir1 && find . -type f ) | sort > list1
( cd dir2 && find . -type f ) | sort > list2
comm -13 list1 list2
Sem linhas terminadas em NULL, a saída aqui é o único elemento ./d
que aparece apenas em list2
.
Gostaria de poder usar find ... -print0 | sort -z
para gerar as listas.
Como posso reimplementar melhor um equivalente para comm
que produza os registros terminados em NULL que aparecem, list2
mas que não aparecem list1
?
O GNU
comm
(a partir do GNU coreutils 8.25) agora tem uma opção-z
/--zero-terminated
para isso.Para versões mais antigas do GNU
comm
, você poderá trocar NUL e NL:Dessa forma,
comm
ainda funciona com registros delimitados por nova linha, mas com novas linhas reais na entrada codificadas como NULs, portanto, ainda estamos seguros com nomes de arquivo contendo novas linhas.Você também pode querer definir a localidade
C
porque em sistemas GNU e na maioria das localidades UTF-8, pelo menos, existem strings diferentes que classificam o mesmo e causariam problemas aqui¹.Esse é um truque muito comum (consulte Inverter linhas correspondentes, separadas por NUL para outro exemplo com
comm
), mas precisa de utilitários que suportem NUL em sua entrada, o que fora dos sistemas GNU é relativamente raro.¹ Exemplo:
( edição de 2019 : a ordem relativa de ①②③ foi corrigida em versões mais recentes do GNU libc, mas você pode usar ? ? ? em vez disso, por exemplo, em versões mais recentes (2.30 pelo menos) que ainda têm o problema como 95% dos pontos de código Unicode )