З урахуванням двох дерев каталогів, як я можу дізнатися, які файли відрізняються за змістом?


786

Якщо я хочу знайти відмінності між двома деревами каталогу, я зазвичай просто виконую:

diff -r dir1/ dir2/

Це виводить саме ті відмінності між відповідними файлами. Мені цікаво лише отримати список відповідних файлів, вміст яких відрізняється. Я припускав, що це просто питання передачі параметра командного рядка diff, але я не зміг знайти нічого на сторінці man.

Будь-які пропозиції?



1
Щодо одного з каталогів, як отримати лише додаткові файли / каталоги в іншому?
Сандепіан Нат

використовувати dircmpкоманду на unix (не linux)
roblogic

Відповіді:


1118

Ви сказали Linux, тож вам пощастить (принаймні, він повинен бути доступний, не впевнений, коли він був доданий):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options

Слід робити те, що потрібно.

Якщо ви також хочете побачити відмінності для файлів, які можуть не існувати в жодному каталозі:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options

12
Приємно. Але коротше diff -qr dir1/ dir2/і моя розширена версіяdiff -qr dir1/ dir2/ | grep ' differ'
sobi3ch

1
@skv чому? Це та сама команда, що і відповідь. Я змінив лише --briefїї ярлик -q.
sobi3ch

2
@skv Не зовсім те, що було задано в оригінальному запитанні, але оновлення відповіді, щоб відповідати цьому питанню.
Марк Лозер

3
@MikeMaxwell Це має бути --brief. -briefтрактується як -b -r -i -e -f, іншими словами, як набір прапорів, а не як єдиний варіант.
даборосс

2
@daboross: Нічого собі, я використовував Unix / Linux протягом певного часу, і ніколи не зрозумів, що існує різниця між "-" і "-". (Я не думаю, що "-" існувало, коли я почав працювати.) Дякую за пояснення!
Майк Максвелл

287

Я використовую команду:

diff -qr dir1/ dir2/

Це точно так само, як у Марка :) Але його відповідь турбував мене, оскільки він використовує різні типи прапорів, і це змусило мене виглядати двічі. Використовуючи більш багатослівні прапори Марка, це було б:

diff  --brief --recursive dir1/ dir2/

Прошу вибачення за публікацію, коли інша відповідь цілком прийнятна. Не міг зупинити себе ... працюючи над тим, щоб бути менш педантичним.


3
повністю ціную послідовність - але не відчувайте себе погано; Я також підтримав відповідь Марка;)
Джерард ONeill

10
..Та чи має сенс туди ставити різні відповіді, ЩО ДУЖЕ різний аромат? ІМХО ні! Чи має сенс поєднувати обидві відповіді на одну послідовну відповідь? так! ;)
sobi3ch

1
Лише питання; що означає qпідставка? Це абревіатура чогось? Я не можу знайти жодної логіки за q..
kramer65

3
@ kramer65 - це те саме, що "--brief", але я думаю, вам цікаво, чому q? Можливо, на швидку? "-b" приймається "ігнорувати зміни кількості пробілу" відповідно до сторінки man.
FPC

4
@ kramer65 Я вважаю, що qце для quiet, загалом, означає менш багатослівний.
Gogeta70

105

Мені подобається використовувати git diff --no-index dir1/ dir2/, тому що він може показувати відмінності в кольорі (якщо у вас є цей параметр, встановлений у вашому git config) і тому, що він показує всі відмінності у довготривалій виводці, використовуючи "менше".


25
Акуратний. Хто б здогадався, що git може відрізнятись довільними каталогами, а не лише репо-файлами проти своїх файлів?
Дан Даскалеску

2
Тут дуже корисний Perl скрипт colordiff , його можна використовувати з svn та нормальним розл.
Феліпе Альварес

4
Якщо ви порівнюєте (як я) 2 режими як окремі проекти git / repos, то вам потрібно додати --no-indexбільше на stackoverflow.com/a/1792477/473390 . Я оновив відповідь @ alan-porter.
sobi3ch

Мені це подобається, я також вважаю, що якщо ви додасте --name-status до командного рядка, він просто покаже список імен файлів із прапорцями "M / A / D" для зміненого / доданого / видаленого статусу.
гж

Буває так, що обидва каталоги насправді містять папку .git, як я можу виключити її із порівняння?
Muhamed Cicak

35

Ці дві команди в основному виконують те, що потрібно:

diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt

rsync --recursive --delete --links --checksum --verbose --dry-run /dir1/ /dir2/ > dirdiff_2.txt

Вибір між ними залежить від місця розташування dir1 та dir2:

Коли каталоги знаходяться на двох відокремлених накопичувачах, розміна перевершує rsync. Але коли два порівняні каталоги знаходяться на одному диску, rsync відбувається швидше. Це тому, що diff ставить майже рівномірне навантаження на обидва каталоги паралельно, максимізуючи навантаження на два диски.

rsync обчислює контрольні суми великими шматками, перш ніж їх фактично порівнювати. Це групує операції вводу / виводу у великі куски та призводить до ефективнішої обробки, коли речі відбуваються на одному диску.


3
Rsync не тільки швидше файли на окремих дисках, але також сіточки для порівняння файлів в підкаталогах, наприклад , rsync --options /usr /bin /var /sbin /lib /old_rootбуде ефективно порівнювати поточний корінь /(вказавши всі підкаталоги в ньому) і /old_root(що містять, наприклад , деякі старі резервні копії /), що - то diff -rможе , не робити. І якщо ви припускаєте, що файли однакового розміру, дозволів та часових позначок, ймовірно, не змінилися, то вихід із системи --checksumдозволить вам надзвичайно швидко (якщо не так - через) перевірити, які файли можуть бути змінені.
Matija Nalis

1
Яка мета --deleteз rsync?
Том Хейл

2
Мета --delete - видалити існуючі файли в призначення-dir, які більше (вже не) присутні у source-dir
Thomas Munk,

2
У цьому випадку (з --dry-runпрапором) насправді нічого не видаляється, rsyncтільки друкується, які файли знаходяться в dir1, але не в dir2
mata

11
Я б рекомендував ставити --dry-runперше завжди, щоб випадково його не забути.
Дейв Раджер

22

Meld також є чудовим інструментом для порівняння двох каталогів:

meld dir1/ dir2/

У Meld є багато варіантів порівняння файлів чи каталогів. Якщо два файли відрізняються, легко ввести режим порівняння файлів і побачити точні відмінності.


2
Приємно. Я написав простий сценарій perl для порівняння по деревах, але я стикаюся з обмеженнями. Це, здається, квиток.
Девід Тонхофер

Єдина проблема полягає в тому, що він не піддається сценаріям, оскільки це графічний додаток. Але приємно, якщо ви не заперечуєте проти графічного інтерфейсу! Дякую.
DeanM

Я вважаю, що це meldстає жахливо млявим, якщо він використовується у великих каталогах. Чи є щось, що краще обробляє великі каталоги?
Popup

@ Popup, не те, що я знаю. Однак ви можете знайти різні назви файлів приблизно так:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
Олександр

1
@Alexander - У такому випадку я вважаю, що це meld <(find dir1 -ls ) <(find dir2 -ls)працює досить добре, використовуючи підстановку bash. (zsh =(command)працює навіть краще.)
Popup

10

Співвітчинець каналу "рахунки" (freenode / # centos fame) поділився зі мною своїм методом:

diff -Naur dir1/ dir2

Включення остаточної косої риски прямого каталогу не має значення.

Крім того, видається, що -uпараметр недоступний для деяких старих / серверних версій розл.

Різниця в різниці:

# diff -Nar /tmp/dir1 /tmp/dir2/
diff -Nar /tmp/dir1/file /tmp/dir2/file
28a29
> TEST

# diff -qr /tmp/dir1/ /tmp/dir2/
Files /tmp/dir1/file and /tmp/dir2/file differ

2
Отож, це --new-file/-Nробить розрізнення вважати відсутні файли порожніми, а --text/-aце призводить до того, що всі двійкові введення вважаються текстовими. Я не бачу переваг для цього конкретного випадку використання.
phk

4

Diffoscope - це чудовий інструмент, що базується на розрізі командного рядка.

Особливо мені подобається про це , що він може дифф в файли:

Він буде рекурсивно розпаковувати архіви багатьох видів і перетворювати різні бінарні формати в більш зручні для людини форми для їх порівняння. Він так само легко може порівняти два тарболи, ISO зображення або PDF.

Він не тільки розкаже, які файли відрізняються, але і як вони відрізняються.


4

Щоб знайти diff, використовуйте цю команду:

diff -qr dir1/ dir2/

-r також буде відрізнятись усіх підкаталогів -q повідомляє diff повідомляти лише тоді, коли файли відрізняються.

diff  --brief dir1/ dir2/

--brief покаже файли, які дозують у каталозі.

Інакше

ми можемо використовувати Meld, який покаже в графічному вікні його легко знайти різницю.

meld  dir1/ dir2/

2
--briefі -qє тим самим варіантом. У вашій заяві звучить так, ніби вони різні, але ні.
Ілля Лінн

2

Ви також можете використовувати Rsyncі find. Для find:

find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER

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

Якщо ви шануєте GUI, ви можете перевірити Meld, який @Alexander згадав. Він чудово працює як в Windows, так і в Linux.


1

Повідомляти про відмінності між dirA та dirB, а також оновлювати / синхронізувати.

rsync -auv <dirA> <dirB>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.