Для створення списку нових або модифікованих файлів програмно найкращим рішенням, який я міг би придумати, є використання 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