Я хочу запустить команду Linux, которая будет рекурсивно сравнивать два каталога и выводить только имена файлов разных. Это включает в себя все, что присутствует в одном каталоге, а не другом или наоборот, и текстовые отличия.
Diff для вывода только имен файлов
Ответ 1
На странице diff man:
-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
Ответ 2
Вы также можете использовать rsync
rsync -rv --size-only --dry-run /my/source/ /my/dest/ > diff.out
Ответ 3
Если вы хотите получить список файлов, которые находятся только в одном каталоге, а не в их подкаталогах и только их имена файлов:
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 {}
Ответ 4
В моей Linux-системе для получения только имен файлов
diff -q /dir1 /dir2|cut -f2 -d' '
Ответ 5
Подход к работе diff -qr old/ new/
имеет один главный недостаток: он может пропустить файлы во вновь созданных каталогах. Например. в приведенном ниже примере файл data/pages/playground/playground.txt
не находится на выходе diff -qr old/ new/
, тогда как каталог data/pages/playground/
(поиск в playground.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
запускается с аргументами theses:
-
-r
для "рекурсии в каталоги", -
-c
, чтобы сравнить файлы одинакового размера и только "пропустить на основе контрольной суммы, а не времени и размера", -
-n
выполнить "пробный запуск без внесенных изменений" и -
--out-format="%n"
для вывода обновлений с использованием указанного FORMAT, который является "% n" здесь только для имени файла
Вывод (список файлов) rsync
в обоих направлениях объединяется и сортируется с помощью sort
, и этот отсортированный список затем сжимается путем удаления всех дубликатов с помощью uniq
Ответ 6
rsync -rvc --delete --size-only --dry-run source dir target dir