Могу ли я получить противоположность `diff -q` - сопоставление идентичных файлов без печати их содержимого


13

У меня есть несколько файлов в каталоге, и я хочу проверить, все ли они уникальны. Для простоты предположим, что у меня есть три файла: foo.txt, bar.txtи baz.txt. Если я запустите этот цикл, я проверю их все друг против друга:

$ 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

Для сотен файлов, с которыми я хочу иметь дело, это станет довольно нечитаемым; было бы лучше , чтобы перечислить файлы , которые делают матч, и тогда я могу просмотреть список быстро и убедитесь , что файлы только соответствующим себя. С man-страницы, я бы подумал, что -sвариант сделает это:

$ 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

... однако на самом деле это также распечатывает все содержимое любых файлов, которые отличаются. Есть ли способ подавить это поведение, поэтому я получаю только поведение выше?

В качестве альтернативы, есть ли другой инструмент, который может это сделать ?

Ответы:


6

Если вы просто хотите проверить, идентичны ли два файла, используйте cmp. Чтобы получить вывод только для одинаковых файлов, вы можете использовать

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

diff пытается составить короткий, понятный человеку список различий, и это может занять довольно много времени, поэтому избегайте накладных расходов, если они вам не нужны.


12

Это должно сделать трюк:

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

где dir1и dir2ваши две директории.

Если вы хотите распечатать только соответствующие каталоги из dir1:

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

И также, если вы хотите распечатать только соответствующие каталоги из dir2:

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

Это именно то, что я искал, спасибо!
Джошуа Сойло,

Используется diff -qrsпри сравнении больших файлов (тихо подавляет различия при печати)
marcovtwout

4

Самый быстрый инструмент, написанный для этой цели, - это fdupes (он доступен в репозиториях пакетов Fedora и Ubuntu и…)

Использование:

fdupes -r dir1 dir2

2

Если вам нужно найти идентичные файлы в списке, сначала отсортируйте их по размеру, например, с помощью

ls -S

затем для каждой группы файлов одинакового размера запустите md5sumих, чтобы легко увидеть, какие из них идентичны.

Для больших файлов может быть быстрее первой контрольной суммы только короткий кусок всего файла:

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

а затем выполнить полную контрольную сумму только для подозрительных файлов.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.