54

Каков наилучший и самый простой способ сравнения двух структур каталогов без фактического сравнения данных в файлах? Это отлично работает:

diff -qr dir1 dir2_

Но он действительно медленный, потому что сравнивает файлы тоже. Для этого есть переключатель diff или другой простой инструмент cli?

9 ответов9

36

Следующее (если вы замените первый каталог на directory1, а второй на directory2) должно сделать то, что вы ищете, и быстро:

find directory1 -type d -printf "%P\n" | sort > file1
find directory2 -type d -printf "%P\n" | sort | diff - file1

Основополагающий принцип состоит в том, что он распечатывает все каталоги, включая пути к подкаталогам, относительно базовых каталоговN.

Это может упасть (произвести странный вывод), если у вас есть возврат каретки в некоторых именах каталогов, но нет других.

34
vimdiff <(cd dir1; find . | sort) <(cd dir2; find . | sort)

предоставит вам хорошее параллельное отображение двух иерархий каталогов с согнутыми общими разделами.

23

Я обычно использую rsync для этой задачи:

rsync -nav --delete DIR1/ DIR2

БУДЬТЕ ОЧЕНЬ ОСТОРОЖНЫ, чтобы всегда использовать опцию -n , aka --dry-run , или она будет синхронизировать (изменять содержимое) каталогов.

Это будет сравнивать файлы на основе времени изменения размера и размера ... Я думаю, это то, что вы действительно хотите, или, по крайней мере, вы не возражаете, если это так? У меня есть ощущение, что вы просто хотите, чтобы это происходило быстрее, а не для того, чтобы игнорировать разницу между содержимым файлов. Если вы хотите, чтобы в нем не отображались разные файлы с одинаковыми именами, я думаю, что добавление --ignore-existing сделает это.

Также имейте в виду, что отсутствие / в конце DIR1 приведет к тому, что он сравнит каталог DIR1 с содержимым DIR2 .

Вывод будет немного многословным, но он покажет вам, какие файлы / каталоги различаются. К файлам / каталогам, присутствующим в DIR2 а не в DIR1 будет добавлено слово « deleting .

В некоторых ситуациях ответ @ slartibartfast может быть более подходящим, хотя вам нужно удалить опцию -type d чтобы включить вывод файлов, не относящихся к каталогу. rsync будет быстрее, если вы сравните значительное количество файлов / каталогов.

17

Аналогичен ответу ls, но если вы установите дерево, вы можете

tree dir1 > out1
tree dir2 > out2
diff out1 out2
3

Я просто искал решение этой проблемы. Решение, которое мне понравилось больше всего, было:

comm <(ls DIR1) <(ls DIR2)

Это дает вам 3 столбца: 1 - файлы только в DIR1, 2 - файлы только в DIR2, 3 - файлы только в DIR3. Для получения более подробной информации смотрите этот пост в блоге.

2

Это оптимальное решение

diff --brief -r dir1 dir2

Переключатель --brief сообщает только о различиях в файлах, а не о различиях

2
ls > dir1.txt

ls > dir2.txt

Затем просто рассмотрите два списка.

1

используйте "diff -qr", чтобы получить разные файлы, а затем отфильтруйте сравнение файлов с помощью grep, чтобы получить только имена файлов, которые находятся только в одном из каталогов.

diff -qr dir1 dir2 | grep -v "Files.*differ" 
-3

Я думаю, что только rsync удобен. Зачем?

diff полезен только для структур, хранящих файлы и каталоги. Diff не дает адекватных кодов выхода, когда мы используем символические ссылки. В этой ситуации diff может вернуть 2 кода выхода, даже если src и dst идентичны (время, размеры, имена, временные метки, указывающие программные ссылки и т.д.).

dir, файловая система не гарантирует порядок файлов, даже если содержимое каталогов в src и dst идентично. Возможно, вам следует отфильтровать вывод ls, отсортировав его. Но чистый ls отображает только имена узлов.

возможно, сценарий, включающий diff, cmp, test -X для типов узлов, будет полезен, но помните о перегрузке, сделанной многими запусками test/cmp. Сценарий будет очень медленным.

Как обычно, если вы хотите получить простую информацию "dirs is/ not same", вы должны использовать rsync с опцией -n (dry). Если вы хотите найти отличия, используйте команду diff.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .