¿Puedo get lo opuesto a `diff -q` – haciendo coincidir los files idénticos sin imprimir sus contenidos

Tengo varios files en un directory y quiero verificar que sean únicos. Para simplificar, digamos que tengo tres files: foo.txt , bar.txt y baz.txt . Si ejecuto este ciclo, los verifico uno contra el otro:

 $ 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 los cientos de files que quiero tratar, esto sería bastante ilegible; Sería mejor hacer una list de los files que coinciden, y luego puedo revisar la list rápidamente y asegurarme de que los files solo coincidan. Desde la página de manual, habría pensado que la opción -s lograría esto:

 $ 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 

… sin embargo, de hecho también imprime todo el contenido de los files que difieren. ¿Hay alguna forma de suprimir este comportamiento, así que solo obtengo el comportamiento anterior?

Alternativamente, ¿hay alguna otra herramienta que pueda lograr esto ?

Si solo desea comprobar si dos files son idénticos o no, use cmp . Para get un resultado solo para files idénticos, puede usar

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

diff intenta producir una list breve y legible por humanos de las diferencias, y esto puede llevar bastante time, así que evite los gastos generales si no lo necesita.

Esto debería funcionar:

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

donde dir1 y dir2 son tus dos directorys.

Si desea imprimir solo los directorys correspondientes de dir1 :

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

Y del mismo modo, si solo desea imprimir los directorys correspondientes de dir2 :

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

La herramienta más rápida escrita para tal fin es fdupes (está disponible en el repository de packages de Fedora y Ubuntu y …)

Uso:

 fdupes -r dir1 dir2 

Si necesita encontrar files idénticos en una list, primero ordénelos por tamaño, por ejemplo con

 ls -S 

luego, para cada grupo de files de tamaño idéntico, ejecute md5sum en ellos para ver fácilmente cuáles son idénticos a los que.

Para files grandes, podría ser más rápido para la primera sum de comprobación solo una pequeña parte del file completo:

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

y luego realice una sum de comprobación completa solo en los files sospechosos.