Файли різниць у двох різних каталогах


303

У мене є два каталоги з тим самим списком файлів. Мені потрібно порівняти всі файли, присутні в обох каталогах за допомогою diffкоманди. Чи є простий варіант командного рядка, щоб це зробити, або мені потрібно написати скрипт оболонки, щоб отримати список файлів, а потім повторити їх?

Відповіді:


422

Ви можете використовувати diffкоманду для цього:

diff -bur folder1/ folder2/

Це виведе рекурсивний розріз, який ігнорує пробіли, з уніфікованим контекстом:

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

9
Ви можете отримати доступ до diffкоманди, завантаживши утиліти GNU для Win32 .
Лоран Етьембл

7
Я також виявив, що - короткий варіант корисний; ви отримаєте список змінених файлів і можете обробити їх окремо
Даріуш,

27
Для інших, хто цікавиться, -bігнорує зміни пробілів і -uнадає 3 рядки буфера.
rattray

28
Простіше запам’ятати цю команду, якщо ви використовуєте rub замість bur, тобтоdiff -rub folder1/ folder2/
SomeGuyOnAComputer

11
Я думаю, -burбуло б легко запам'ятати, якби ти жив у холодному кліматі.
AlanH

126

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

diff -qr dir_one dir_two | sort

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


1
Це здорово! Також працює ефективно - тобто, якщо цілий підкаталог існує лише в одному з dirs, його зупинка повторюється в ньому і повідомляє лише про сам підреєстр (без вмісту правонаступника). дуже хороша!!
Щось щось щось

Це дійсно хороший перший крок: подивіться, чим вони відрізняються, а потім зробіть детальну інформацію 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
@Dennis, прикольний ярлик. +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
Це дублює наявну відповідь і не додає нового вмісту. Будь ласка, не публікуйте відповіді, якщо у вас насправді є щось нове.
Toby Speight
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.