Як розрізнити каталог лише для файлів певного типу?


87

У мене питання про команду diff, якщо я хочу рекурсивний каталог diff, але лише для певного типу файлу, як це зробити?

Я спробував використовувати параметр виключення, але можу використовувати лише один шаблон:

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

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

як розрізняти лише певні типи файлів -.



Отже, ви намагаєтесь розрізнити файли певного типу або виключити ці файли з відмінностей? Питання не відповідає опису.
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. На відміну від оболонки, точка на початку основи імені файлу відповідає підстановці на початку шаблону. Ви повинні вкласти PATTERN у лапки, щоб оболонка не розширювала його. Наприклад, параметр -x '*. [Ao]' ігнорує будь-який файл, ім'я якого закінчується на '.a' або '.o'.

Цей параметр накопичується, якщо ви вказали його більше одного разу. Наприклад, використовуючи параметри -x 'RCS' -x '*, v' ігнорує будь-який файл або підкаталог, базове ім'я якого 'RCS', або закінчується на ', v'.


У Mine (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]"- це нормально, але це не дуже
наочно

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 

Супер корисний однокласний, thx. На 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. Просто запустіть: "make patch"

#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, якщо хочете отримати файли, які існують лише в одному із шляхів.


0

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

diff -ruNp /path/1 /path/2 | filterdiff -i "*.py" | tee /path/to/file.patch
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.