Posso ottenere il contrario di `diff -q` - abbinare file identici senza stamparne il contenuto


13

Ho un numero di file in una directory e voglio verificare che siano tutti unici. Per semplicità, diciamo che ho tre file: foo.txt, bar.txte baz.txt. Se eseguo questo ciclo, li controllerò tutti l'uno contro l'altro:

$ 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

Per le centinaia di file che voglio trattare, questo diventerebbe piuttosto illeggibile; sarebbe meglio per elencare i file che fanno match, e quindi posso guardare oltre l'elenco in modo rapido e fare in modo che i file siano in abbinamento solo se stessi. Dalla manpage, avrei pensato che l' -sopzione avrebbe ottenuto questo risultato:

$ 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

... tuttavia, in realtà anche di stampare l'intero contenuto di tutti i file che differiscono. C'è un modo per sopprimere questo comportamento, quindi ottengo solo il comportamento sopra?

In alternativa, c'è qualche altro strumento che può realizzare questo ?

Risposte:


6

Se vuoi solo controllare se due file sono identici o meno, usa cmp. Per ottenere un output solo per file identici, è possibile utilizzare

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

diff cerca di produrre un breve elenco leggibile dall'uomo delle differenze, e questo può richiedere parecchio tempo, quindi evita il sovraccarico se non ne hai bisogno.


12

Questo dovrebbe fare il trucco:

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

dove dir1e dir2sono le tue due directory.

Se desideri stampare solo le directory corrispondenti da dir1:

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

E allo stesso modo, se desideri stampare solo le directory corrispondenti da dir2:

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

Questo è esattamente quello che stavo cercando, grazie!
Joshua Soileau,

Utilizzare diff -qrsquando si confrontano file di grandi dimensioni (elimina silenziosamente le differenze di stampa)
marcovtwout,

4

Lo strumento più veloce scritto a tale scopo è fdupes (è disponibile nei repository di pacchetti di Fedora e Ubuntu e ...)

Uso:

fdupes -r dir1 dir2

2

Se è necessario trovare file identici in un elenco, innanzitutto ordinarli per dimensione, ad esempio con

ls -S

quindi per ogni gruppo di file di dimensioni identiche, esegui md5sumsu di essi per vedere facilmente quali sono identici a quali.

Per i file di grandi dimensioni, potrebbe essere più veloce prima eseguire il checksum solo una breve parte dell'intero file:

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

e quindi eseguire un checksum completo solo su file sospetti.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.