Как разграничить каталог только для файлов определенного типа?

88

У меня есть вопрос о команде diff, если мне нужен рекурсивный каталог diff, но только для определенного типа файла, как это сделать?

Я пробовал использовать опцию exclude, но могу использовать только один шаблон:

$ diff /destination/dir/1 /destination/dir/2 -r -x *.xml

с помощью команды я могу исключить только тип XML - файл, даже если есть файлы типа папки изображений ( png, gif, jpg), txt, phpи т.д.

как различать только определенные типы файлов.

de_3
источник
1
stackoverflow.com/q/10131908/2707864
sancho.s ReinstateMonicaCellio
Итак, вы пытаетесь сравнить файлы определенного типа или исключить эти файлы из сравнения? Вопрос не соответствует описанию ..
def

Ответы:

97

Вы можете указать -xболее одного раза.

diff -x '*.foo' -x '*.bar' -x '*.baz' /destination/dir/1 /destination/dir/2

В разделе «Сравнение каталогов» info diff(в моей системе я должен это сделать info -f /usr/share/info/diff.info.gz):

Чтобы игнорировать некоторые файлы при сравнении каталогов, используйте параметр '-x PATTERN' или '--exclude = PATTERN'. Эта опция игнорирует любые файлы или подкаталоги, базовые имена которых соответствуют шаблону оболочки PATTERN. В отличие от оболочки, точка в начале имени файла соответствует подстановочному знаку в начале шаблона. Вы должны заключить ШАБЛОН в кавычки, чтобы оболочка не расширяла его. Например, опция -x '*. [Ao]' игнорирует любой файл, имя которого заканчивается на '.a' или '.o'.

Этот параметр накапливается, если вы укажете его более одного раза. Например, при использовании параметров -x 'RCS' -x '*, v' игнорируются все файлы или подкаталоги, базовое имя которых - RCS или оканчивается на ', v'.

Приостановлено до дальнейшего уведомления.
источник
В моем (ubuntu 10.04) этих строк нет. Я тоже пробовал, и это не сработало. Думаю, это новая версия.
alumi
22

Взято из (версии) справочной страницы:

-x PAT  --exclude=PAT
  Exclude files that match PAT.

-X FILE    --exclude-from=FILE
  Exclude files that match any pattern in FILE.

Таким образом, похоже, что при -xотправке отчета принимается только один шаблон, но если вы поместите все шаблоны, которые хотите исключить, в файл (предположительно, по одному на строку), вы можете использовать второй флаг следующим образом:

$ diff /destination/dir/1 /destination/dir/2 -r -X exclude.pats

где exclude.pats - это:

*.jpg
*.JPG
*.xml
*.XML
*.png
*.gif
Джеймсбтейт
источник
4
Вы можете найти все расширения файлов в своей папке, кроме расширения <my-ext>, с помощью следующей командной строки:find . -type f -not -name '*.<my-ext>' | xargs -I% basename '%' | awk -F . 'NF > 1 { print "*." $NF}; NF == 1 { print $NF }' | sort | uniq > exclude.pats
Джон,
Мне жаль, что я раньше не заметил комментарий Джона, но в macOs / bash я пришел к аналогичному решению, чтобы создать файл исключения с несколькими шаблонами, которые нужно сохранить: find . -not -name "*.c" -and -not -name "*.h" -and -type f -print0 | xargs -0 basename | grep -E '.*\..+' | sed 's/\./\//g' | xargs basename | xargs printf '*.%s\n' | sort | uniq > X-FILEя хочу верить, что это помогает, может быть, и в Linux. (В этом примере сингл -name "*.[ch]"- это нормально, но это не очень показательно)
eruve
16

Вы также можете использовать find с -exec для вызова diff:

cd /destination/dir/1
find . -name *.xml -exec diff {} /destination/dir/2/{} \;
Алекс Харуи
источник
7

Отсутствие дополнительного - включить ....

Мы можем сделать один обходной путь, исключить файл со всеми файлами, кроме того, что мы хотим включить. Итак, мы создаем file1с помощью поиска все файлы, у которых нет расширений, которые мы хотим включить, sedперехватываем имя файла и просто:

diff --exclude-from=file1  PATH1/ PATH2/

Например:

find  PATH1/ -type f | grep --text -vP "php$|html$" | sed 's/.*\///' | sort -u > file1 
diff PATH1/ PATH2/ -rq -X file1 
Сержио
источник
Супер полезный однострочный, спасибо. На Mac OSX grep немного отличается и становится find PATH1/ -type f | grep --text -v -e "php$" -e html$" | sed 's/.*\///' | sort -u > file1 diff PATH1/ PATH2/ -rq -X file1
mmacvicar
3

Я использовал следующую команду, чтобы найти *.tmplразницу между всеми файлами между DIR1и DIR2. В моем случае это не дало ложных срабатываний, но это может быть для вас, в зависимости от содержимого вашего DIRS.

diff --brief DIR1 DIR2 | grep tmpl

Михаил Голубицкий
источник
2

Если вам это удобно, вы можете использовать следующее Makefile. Просто запустите: "сделать патч"

#Makefile for patches

#Exlude following file endings
SUFFIX += o
SUFFIX += so
SUFFIX += exe
SUFFIX += pdf
SUFFIX += swp

#Exlude following folders
FOLDER += bin
FOLDER += lib
FOLDER += Image
FOLDER += models

OPTIONS = Naur

patch: 
    rm test.patch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
        org/ new/ > test.patch  

unpatch: 
    rm test.unpatch
    diff -$(OPTIONS) \
    $(foreach element, $(SUFFIX) , -x '*.$(element)') \
    $(foreach element, $(FOLDER) , -x '$(element)*') \
    new/ org/ > test.unpatch
Рафиз
источник
1

Отсутствие дополнительного --include заставляет использовать такие запутанные эвристические шаблоны, как

*.[A-Zb-ik-uw-z]*

найти (в основном) файлы java!

Джерри Миллер
источник
1

Если вы хотите использовать разные источники и не усложнять:

diff -rqx "*.a" -x "*.o" -x "*.d" ./PATH1 ./PATH2 | grep "\.cpp " | grep "^Files"

Удалите последний grep, если вы хотите получить файлы, которые существуют только в одном из путей.

Alex
источник
0

Хотя это не позволяет избежать фактического diffиспользования других файлов, если ваша цель - создать файл исправления или что-то подобное, вы можете использовать его filterdiffиз patchutilsпакета, например, для исправления только ваших .pyизменений:

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
Cez
источник