Posso obter o oposto de `diff -q` - combinando arquivos idênticos sem imprimir seu conteúdo


13

Eu tenho vários arquivos em um diretório e quero verificar se todos são únicos. Para simplificar, vamos dizer que tenho três arquivos: foo.txt, bar.txte baz.txt. Se eu executar esse loop, verificarei todos eles um contra o outro:

$ for f in ./*; do for i in ./*; do diff -q "$f" "$i"; done; done
Files bar.txt and baz.txt differ
Files bar.txt and foo.txt differ
Files baz.txt and bar.txt differ
Files baz.txt and foo.txt differ
Files foo.txt and bar.txt differ
Files foo.txt and baz.txt differ

Para as centenas de arquivos com os quais quero lidar, isso se tornaria bastante ilegível; seria melhor para listar os arquivos que fazem jogo, e então eu posso olhar sobre a lista rapidamente e certifique-se de que apenas os arquivos estão se combinando. Na página de manual, eu teria pensado que a -sopção conseguiria isso:

$ for f in ./*; do for i in ./*; do diff -s "$f" "$i"; done; done
Files bar.txt and bar.txt are identical
Files baz.txt and baz.txt are identical
Files foo.txt and foo.txt are identical

... no entanto, na verdade, ele também imprime todo o conteúdo de qualquer arquivo que seja diferente. Existe alguma maneira de suprimir esse comportamento, então eu só recebo o comportamento acima?

Como alternativa, existe alguma outra ferramenta que pode fazer isso ?

Respostas:


6

Se você quiser apenas verificar se dois arquivos são idênticos ou não, use cmp. Para obter uma saída apenas para arquivos idênticos, você pode usar

for f in ./*; do for i in ./*; do cmp -s "$f" "$i" && echo "Files $f and $i are identical"; done; done

diff tenta produzir uma lista curta e legível das diferenças, e isso pode levar bastante tempo, portanto evite a sobrecarga se você não precisar.


12

Isso deve fazer o truque:

diff -rs dir1 dir2 | egrep '^Files .+ and .+ are identical$'

onde dir1e dir2são seus dois diretórios.

Se você deseja imprimir apenas os diretórios correspondentes de dir1:

diff -rs dir1 dir2 | egrep '^Files .+ and .+ are identical$' | awk -F '(Files | and | are identical)' '{print $2}'

Da mesma forma, se você deseja imprimir apenas os diretórios correspondentes em dir2:

diff -rs dir1 dir2 | egrep '^Files .+ and .+ are identical$' | awk -F '(Files | and | are identical)' '{print $3}'

Era exatamente isso que eu procurava, obrigado!
Joshua Soileau

Use diff -qrsquando comparando arquivos grandes (silencioso suprime a impressão de diferenças)
marcovtwout

4

A ferramenta mais rápida escrita para esse fim é fdupes (está disponível nos repositórios de pacotes do Fedora e Ubuntu e…)

Uso:

fdupes -r dir1 dir2

2

Se você precisar encontrar arquivos idênticos em uma lista, primeiro os classifique por tamanho, por exemplo, com

ls -S

depois, para cada grupo de arquivos de tamanhos idênticos, execute md5sum -os para ver facilmente quais são idênticos a quais.

Para arquivos grandes, pode ser mais rápido primeiro adicionar apenas um pequeno pedaço do arquivo inteiro:

dd if=file bs=512 count=1 | md5sum

e execute uma soma de verificação completa apenas em arquivos suspeitos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.