Відповіді:
Зі сторінки чоловіка diff:
-q
Повідомте лише про те, чи відрізняються файли, а не деталі відмінностей.
-r
Порівнюючи каталоги, рекурсивно порівнюйте знайдені підкаталоги.
Приклад команди:
diff -qr dir1 dir2
Приклад виводу (залежить від місцевості):
$ ls dir1 dir2
dir1:
same-file different only-1
dir2:
same-file different only-2
$ diff -qr dir1 dir2
Files dir1/different and dir2/different differ
Only in dir1: only-1
Only in dir2: only-2
-x PATTERN
в команду для виключення певних підкаталогів. Наприклад, diff -qr repo1 repo2 -x ".git"
порівняємо два каталоги, але виключатиме шляхи до файлів з ".git" в них.
Ви також можете використовувати rsync
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
--size-only
буде пропускати файли однакового розміру, але різного вмісту, наприклад, старий / версія.txt "29a" new / version.txt "29b" . Використовуйте натомість: rsync -ric --dry-run old/ new/
де аргумент "-i" дозволяє отримати список файлів безпосередньо черезrsync -ric --dry-run old/ new/ | cut -d" " -f 2
Якщо ви хочете отримати список файлів, які знаходяться лише в одному каталозі, а не їхні підкаталоги та лише їхні назви файлів:
diff -q /dir1 /dir2 | grep /dir1 | grep -E "^Only in*" | sed -n 's/[^:]*: //p'
Якщо ви хочете рекурсивно перелічити всі файли та каталоги, які відрізняються за їх повним шляхом:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}'
Таким чином ви можете застосувати різні команди до всіх файлів.
Наприклад, я можу видалити всі файли та каталоги, які знаходяться у dir1, але не у dir2:
diff -rq /dir1 /dir2 | grep -E "^Only in /dir1*" | sed -n 's/://p' | awk '{print $3"/"$4}' xargs -I {} rm -r {}
У моїй системі Linux, щоб отримати лише імена файлів
diff -q /dir1 /dir2|cut -f2 -d' '
audit-0.0.234/audit-data-warehouse-0.0.234/ audit-0.0.235/audit-data-warehouse-0.0.235/
diff -qrN /dir1 /dir2 | cut -f2 -d' '
добре працює для мене!
Підхід до запуску diff -qr old/ new/
має один головний недолік: він може пропускати файли в новостворених каталогах. Наприклад, у наведеному нижче прикладі файл data/pages/playground/playground.txt
не знаходиться у виводі, diff -qr old/ new/
тоді як у каталозі data/pages/playground/
є (пошук для playground.txt у вашому браузері для швидкого порівняння). Я також розмістив наступне рішення на Unix & Linux Stack Exchange , але я скопію його і тут:
Для створення списку нових або модифікованих файлів програмно найкращим рішенням, який я міг би придумати, є використання rsync , сортування та uniq :
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
Поясню на цьому прикладі: ми хочемо порівняти два випуски dokuwiki, щоб побачити, які файли були змінені, а які новостворені.
Ми витягуємо качки з wget і витягуємо їх у каталоги old/
та new/
:
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
Запуск rsync в один спосіб може пропустити новостворені файли, оскільки тут показано порівняння rsync та diff:
rsync -rcn --out-format="%n" old/ new/
дає такий вихід:
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
Запуск rsync лише в одному напрямку пропускає новостворені файли, а в інший бік буде пропущено видалені файли, порівняйте вихід різниці:
diff -qr old/ new/
дає такий вихід:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
Запуск rsync обома способами та сортування виводу для видалення дублікатів виявляє, що каталог data/pages/playground/
та файл data/pages/playground/playground.txt
були пропущені спочатку:
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
дає такий вихід:
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
rsync
працює з аргументами тез:
-r
"повторний пошук у каталогах", -c
також порівнювати файли однакового розміру і лише "пропускати на основі контрольної суми, а не мод-часу та розміру", -n
"виконати пробний запуск без змін", і--out-format="%n"
"вивести оновлення, використовуючи вказаний FORMAT", який тут "% n" лише для імені файлуВихід (список файлів) rsync
обох напрямків поєднується та сортується за допомогою sort
, і цей відсортований список згортається, видаляючи всі дублікати зuniq
diff new/ old/
), щоб побачити, які каталоги видалено?
diff -qr new/ old/
на прикладі вище з dokuwiki tars видає такий же вихід, як diff -qr old/ new/
- тобто ви бачите, що каталог новий / відсутній, але не файли в ньому
diff
сторінка man у CentOS 7 описує-q
як "звітувати лише тоді, коли файли відрізняються", що менш зрозуміло, ніж те, що ви написали.