Ответы:
Со страницы руководства 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
пропустит файлы одинакового размера, но разного содержания, например old / version.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/
(найдите для быстрого просмотра 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
diff new/ old/
), чтобы увидеть, какие каталоги были удалены?
diff -qr new/ old/
приведенного выше примера с докувики tars дает тот же результат, что и diff -qr old/ new/
- т.е. вы видите, что каталог новый / отсутствует, но нет файлов в нем
diff
справочная страница в CentOS 7 описывается-q
как «отчет, только если файлы различаются», что менее понятно, чем то, что вы написали.