Подход запуска diff -qr old/ new/
имеет один существенный недостаток: он может пропустить файлы во вновь созданных каталогах. Например. в приведенном ниже примере файл data/pages/playground/playground.txt
отсутствует в выводе diff -qr old/ new/
, тогда как каталог data/pages/playground/
есть (найдите в браузере plays.txt , чтобы быстро сравнить). Я также разместил следующее решение в Unix & Linux Stack Exchange , но также скопирую его здесь:
Для программного создания списка новых или измененных файлов лучшее решение, которое я мог бы найти, - это использовать rsync , sort и 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:
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"
для «вывода обновлений с использованием указанного ФОРМАТА», что здесь «% n» только для имени файла
Вывод (список файлов) rsync
в обоих направлениях объединяется и сортируется с использованием sort
, и этот отсортированный список затем сокращается путем удаления всех дубликатов с uniq