Czy mogę uzyskać przeciwieństwo `diff -q` - dopasowywanie identycznych plików bez drukowania ich zawartości

13

Mam kilka plików w katalogu i chcę sprawdzić, czy wszystkie są unikalne. Dla uproszczenia załóżmy, że mam trzy pliki: foo.txt, bar.txti baz.txt. Jeśli uruchomię tę pętlę, sprawdzę je wszystkie względem siebie:

$ 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

W przypadku setek plików, z którymi chcę sobie poradzić, byłoby to dość nieczytelne; lepiej byłoby wymienić pliki, które pasują, a następnie mogę szybko przejrzeć listę i upewnić się, że pliki pasują tylko do siebie. Z tej strony pomyślałbym, że -sopcja by to osiągnęła:

$ 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

... jednak w rzeczywistości drukuje również całą zawartość wszystkich plików, które się różnią. Czy jest jakiś sposób na powstrzymanie tego zachowania, więc dostaję tylko powyższe zachowanie?

Alternatywnie, czy jest jakieś inne narzędzie, które może to osiągnąć ?

zła
źródło

Odpowiedzi:

6

Jeśli chcesz tylko sprawdzić, czy dwa pliki są identyczne, czy nie, użyj cmp. Aby uzyskać dane wyjściowe tylko dla identycznych plików, możesz użyć

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

diff stara się stworzyć krótką, czytelną dla człowieka listę różnic, co może zająć sporo czasu, więc unikaj narzutu, jeśli go nie potrzebujesz.

Uwe
źródło
12

To powinno załatwić sprawę:

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

gdzie dir1i dir2są twoje dwa katalogi.

Jeśli chcesz wydrukować tylko pasujące katalogi z dir1:

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

Podobnie, jeśli chcesz wydrukować tylko pasujące katalogi z dir2:

diff -rs dir1 dir2 | egrep '^Files .+ and .+ are identical$' | awk -F '(Files | and | are identical)' '{print $3}'
j0nam1el
źródło
Właśnie tego szukałem, dzięki!
Joshua Soileau
Służy do diff -qrsporównywania dużych plików (cichy tłumi różnice w drukowaniu)
marcovtwout
4

Najszybciej narzędzie napisane w tym celu jest fdupes (jest dostępny w repo pakietów Fedory i Ubuntu i ...)

Stosowanie:

fdupes -r dir1 dir2
erik
źródło
2

Jeśli chcesz znaleźć identyczne pliki na liście, najpierw posortuj je według rozmiaru, na przykład za pomocą

ls -S

następnie dla każdej grupy plików o identycznych rozmiarach uruchom md5sumje, aby łatwo zobaczyć, które są identyczne z którymi.

W przypadku dużych plików szybciej może być najpierw suma kontrolna tylko krótki fragment całego pliku:

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

a następnie wykonaj pełną sumę kontrolną tylko w przypadku podejrzanych plików.

enzotib
źródło