Як я можу зробити так, щоб "diff -X" ігнорував конкретні шляхи, а не імена файлів?


29

Виконуємо: diff -r -X <ignore-list> <src-dir> <dest-dir>

Схоже, не вносять diffзаписи ігнору, <ignore-list>якщо вони мають форму <dir>/<file>.

Записи форми <file> однак враховуються. Це проблема, оскільки у мене можуть бути декілька файлів, названих <file>у різних підкаталогах, деякі з яких я не хочу ігнорувати.

Здається, не так багато інформації щодо синтаксису шаблону на сторінці вручну diff. З того, що я можу сказати, це саме базове ім'я файлу, яке розглядається різницею (див. Http://forums.gentoo.org/viewtopic-t-889788-start-0.html, якщо ви зацікавлені).


людина, diff«s --excludeваріант так хреново ...
Elouan Keryell-Навіть

Відповіді:


30

Лістинг каталогів повинен працювати; наприклад, ось що я використав у сценарії (припустимо, що gnu diff),

diff -r \
   --exclude="*~" \
   --exclude=".svn" \
   --exclude=".git" \
   --exclude="*.zip*" \
   --exclude="*.gz" \
   --exclude="*.tar" \
   ...etc

... який ігнорує вміст .svnта .gitdirs, а також окремі файли з ім’ям *.zip/ *.gz/ тощо.

Редагувати: для того, щоб фільтрувати шляхи форми, dir_a/file1але все-таки diffфайли з тим самим базовим іменем, як, dir_b/file1або dir_a/b/file1, тоді слід diffбуло б створити список файлів (наприклад, використовуючи find) та файл для порівняння похідних із цих шляхів; наприклад, дано

$ find ONE TWO -type f -print 
ONE/a/1.txt
ONE/a/2.txt
ONE/a/b/2.txt
TWO/a/1.txt
TWO/a/2.txt
TWO/a/b/2.txt

ви генеруєте список файлів для порівняння, виключаючи, наприклад, */a/2.txtале все ж порівнюючи інші файли з назвою 2.txt. Просто "знайдіть" усі файли, за винятком ONE/a/2.txt(тут також може бути використаний регулярний вираз, наприклад .*/a/2.txt)

$ find ONE -type f \( ! -regex 'ONE/a/2.txt' \) \
    -exec bash -c 'diff -q "${1}" "${2/ONE/TWO}"' - {} {} \;  

який фактично ігнорує ONE/a/2.txtTWO/a/2.txt), але все ж порівнює інші файли з назвою 2.txt:

diff -q ONE/a/1.txt TWO/a/1.txt
diff -q ONE/a/b/2.txt TWO/a/b/2.txt

Редагувати: Або, щоб отримати задоволення find(додаткову забаву, що залишилася для вправлення для читача), виберіть файли чи каталоги, які потрібно виключити, а потім diffвсе інше:

$ find ONE \( -regex 'ONE/a/2.txt' -o -name b  -prune \)  \
    -o -type f -exec bash -c 'echo diff -q "${1}" "${2/ONE/TWO}"' - {} {} \

Наведений вище приклад виключає конкретний файл "{top} /a/2.txt", будь-який каталог з назвою "b", а все інше - розрізнено. (Замість простого " -name b" ви також можете використати " -regex '.*/b'" - зауважте, немає трейлінгу "/".)


2
Дякую, але я думаю, що ви пропускаєте суть. Здається, єдина підтримка, коли ви використовуєте "базове ім'я". Це може бути назва каталогу або файлу. В будь-якому випадку, diff ігнорує те, що ви просили. Проблема виникає при використанні шляхів. Наприклад, я не можу отримати різницю в ігноруванні / an / absolut / path / to / a / file або ./a/relative/path/to/a/file.
Еш

2
diff --exclude = "/ цей / конкретний / файл / що / ім / явно / благаючи / ви / до / ігнорувати". Це не спрацює.
Еш

3
правильно, excludeшаблони підбираються до базового імені файлів (відповідно до gnu.org/software/diffutils/manual/html_node/… ); шляхи не працюватимуть (як у foo/bar.txt). Для цього вам, ймовірно, доведеться запустити findдля створення списку імен файлів і вивести шлях до файлу для порівняння.
michael

оновлена ​​відповідь, щоб включити приклад, що виключає шляхи до файлів diff, а не просто використовуватиbasename
michael

Гаразд, я бачу, що ви пропонуєте, але, мабуть, є проблема. Мені потрібно також враховувати каталоги, а не лише файли (тобто -типи f). Тепер, поки ви ще можете вирізати певні файли за допомогою regexp find, якщо вхід diffмістить каталог, він буде проходити і порівнювати файли в цьому каталозі, і деякі з цих файлів, можливо, потрібно буде проігнорувати .... так що ви назад до площі 1.
Еш,


1

Для виключення каталогу directory/sub-directoryя використовую

diff -r <src-dir> <dest-dir> | grep -v directory/sub-directory

Однак, хоча він повинен працювати для одного виключення, він не повинен бути можливим для тривалого ігнорування списку, як у вас є.


-2
$ diff -rq foo.orig foo | grep -vP 'ignore1/|exclude2/' | awk '{print $2}' | cut -d'/' -f2- | xargs -I{} diff -u foo.orig/{} foo/{}

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