27

Выполнение:diff -r -X <ignore-list> <src-dir> <dest-dir>

похоже, что diff игнорирует записи в <ignore-list> если они имеют форму <dir>/<file> .

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

Похоже, в справочной странице для diff также нет большой информации о синтаксисе шаблонов. Из того, что я могу сказать, это просто базовое имя файла, который рассматривается diff (см. Http://forums.gentoo.org/viewtopic-t-889788-start-0.html, если вам интересно).

4 ответа4

27

Списки каталогов должны работать; например, вот что я использовал в сценарии (при условии, что GNU diff),

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

... который игнорирует содержимое .svn и .git , а также отдельные файлы с именем *.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" и все остальное diff diff. (Вместо простого " -name b " вы также можете использовать " -regex '.*/b' " - примечание, без трейлинга "/".)

2

У меня была такая же проблема, поэтому я создал патч для diff . Патч еще не принят, но вы можете создать свою собственную версию diff с патчем или установить на Arch Linux с пакетом AUR .

Вот патч для diff .

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/{}

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