Разные файлы представлены в двух разных каталогах


303

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

Ответы:


422

Вы можете использовать diffкоманду для этого:

diff -bur folder1/ folder2/

Это выведет рекурсивный diff, игнорирующий пробелы, с унифицированным контекстом:

  • флаг b означает игнорирование пробелов
  • Флаг u означает единый контекст (3 строки до и после)
  • Флаг r означает рекурсивный

9
Вы можете получить доступ к diffкоманде, загрузив утилиты GNU для Win32 .
Лоран Etiemble

7
Я также обнаружил, что опция --brief полезна; вы получаете список измененных файлов и можете обрабатывать их отдельно
Dariusz

27
Для других интересно, -bигнорирует изменения пробелов и -uдает 3 строки буфера.
Раттрей

28
Это легче запомнить эту команду , если вы используете руб вместо бур тdiff -rub folder1/ folder2/
SomeGuyOnAComputer

11
Я полагаю, -burбыло бы легко запомнить, если бы вы жили в холодном климате.
AlanH

126

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

diff -qr dir_one dir_two | sort

Опция «q» будет показывать только файлы, которые отличаются, но не содержимое, которое отличается, а «сортировка» организует вывод в алфавитном порядке.


1
Это просто супер! Также работает эффективно - то есть, если целый подкаталог существует только в одном из каталогов, он перестает повторяться в нем и сообщает только о самом подкаталоге (без его преемника содержимого). очень хорошо!!
SomethingSomething

Это действительно хороший первый шаг: увидеть , что, если что - нибудь, действительно отличается, а затем сделать подробно diffна каждой паре различных файлов. Один подход был бы совершенно другим, если бы только один или два файла отличались от десятков файлов. Я мог потеряться в выводе из diffдесятков файлов одновременно!
jvriesem

Также может включать -x PATTERNв команду исключение определенных подкаталогов. Например, diff -qr repo1 repo2 -x ".git"будет сравнивать две директории (repo1 и repo2), но исключит файлы в папке .git соответствующих каталогов.
ViFI

20

У Diff есть опция, -rкоторая предназначена именно для этого.

diff -r dir1 dir2


11

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

$ man diff

...

-r  --recursive
        Recursively compare any subdirectories found.

...

3

Если это GNU diff, вы должны просто указать его на две директории и использовать опцию -r.

В противном случае попробуйте использовать

for i in $(\ls -d ./dir1/*); do diff ${i} dir2; done

NB. Как отметил Деннис в разделе комментариев, вам на самом деле не нужно выполнять подстановку команд в ls. Я делал это так долго, что в значительной степени делаю это на автопилоте и подставляю команду, необходимую для получения списка файлов для сравнения.

Также я забыл добавить, что я делаю '\ ls', чтобы временно отключить мой псевдоним ls для GNU ls, чтобы я потерял информацию о форматировании цвета из списка, возвращаемого GNU ls.


2
Нет необходимости использовать ls:for i in ./dir1/*
Приостановлено до дальнейшего уведомления.

1
@ Денис, прикольный ярлык. +1. Я так привык выполнять подстановку команд, хотя она автоматическая, и я просто использую любую нужную мне команду, например, иногда я использую find. Использование ls также позволяет мне больше использовать список dir, например, обратное время вместо последовательности по умолчанию.
Роб Уэллс

0

Вот скрипт, чтобы показать различия между файлами в двух папках. Работает рекурсивно. Измените dir1 и dir2.

(search() { for i in $1/*; do [ -f "$i" ] && (diff "$1/${i##*/}" "$2/${i##*/}" || echo "files: $1/${i##*/}   $2/${i##*/}"); [ -d "$i" ] && search "$1/${i##*/}" "$2/${i##*/}"; done }; search "dir1" "dir2" )

0

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

diff <(find DIR1 -printf '%P\n' | sort) <(find DIR2 -printf '%P\n' | sort) | grep '^[<>]'

-printf '%P\n' говорит find не префиксировать выходные пути с корневым каталогом.

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

В grepконце удаляется информация об идентичных строках ввода.


-4

Попробуй это:

diff -rq /path/to/folder1 /path/to/folder2      

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