Encontre arquivos que não existem em outro diretório

Encontre arquivos que não existem em outro diretório

Preciso encontrar todos os arquivos que existem em qualquer lugar do dir1, mas não existem em nenhum lugar do dir2. dir1e dir2pode ter estrutura diferente, por isso diff -rnão funciona bem.

Responder1

Tente fazer uma lista de arquivos sem caminho. Dessa forma, você pode comparar dois diretórios. No entanto, os nomes dos arquivos devem ser todos diferentes. Se você tiver o mesmo nome de arquivo repetido em dir1 em subdiretórios diferentes, a remoção do caminho removerá a exclusividade do nome do arquivo. Você pode obter uma lista de cada diretório sem nomes de caminho como este:

find dir1/ -exec basename {} \; | sort
find dir2/ -exec basename {} \; | sort

Todos juntos seriam algo assim

diff <(find dir1/ -exec basename {} \; | sort) <(find dir2/ -exec basename {} \; | sort)

Vejo que há um comentário sugerindo o uso de fdupes. fdupesse definitivamente uma solução melhor.

Responder2

Um método bruto poderia estar usando md5sum. Esteja ciente de que arquivos com comprimento zero sempre serão vistos como duplicados, portanto, você pode querer findapenas arquivos com tamanho de pelo menos um byte.

find /first/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path1.txt
cut -b1-32 < /tmp/md5-path1-short.txt
find /second/path -type f -exec md5sum -b \{\} \; > /tmp/md5-path2.txt
cut -b1-32 < /tmp/md5-path2-short.txt

Arquivos no caminho1 que não estão no caminho2 (remova a opção '-v'

grep /tmp/md5-path1.txt -v -F -f /tmp/md5/path2-short.txt

Nível CYA: profissional

O 32 acima ocorre porque os hashes MD5 têm 32 bytes de comprimento. Se você usasse, digamos, sha1sum, que tem uma chance ainda menor de colisões, usaria um comprimento de 40; sha224sumrequer 56, sha256sumrequer 64 e sha512sum128.

Nível CYA: paranóico

Isto pode não funcionar em alguns esquemas de cache nos quais os metadados são mantidos em arquivoscujo nome contém o hash do arquivo original.

(isso realmente aconteceu comigo com uma instalação do Wordpress + Magento anos atrás, onde queríamos migrar um enorme cache de artigos enquanto removíamos entradas obsoletas).

Nesse caso você teria que usar um esquema de hash diferente - solução rápida - para evitar grepretornar falsos positivos, confundindo a entrada de metadados com o arquivo original (portanto, use SHA1 se o cache usar MD5 ou vice-versa); ou usar sedpara reescrever todas as linhas nos arquivos "curtos" para adicionar um "^" no início, transformando-o em um regex ancorado e removendo o -Fsinalizador de greppara processar o arquivo como regexes em vez de strings simples.

Responder3

Então, a solução parcial que encontrei é:

find dir1 -type f | grep -vxFf <(fdupes -r dir1 dir2)

mas digo "parcial", porque se houver duplicatas em dir1, elas não serão mostradas, então você precisa executar fdupes -r dir1primeiro.

informação relacionada