Сравнить 2 каталога и скопировать различия в 3-й каталог

Запустив ubuntu 12.04, я хочу сравнить 2 директории, скажем folder1/ и folder2/, и скопировать любые файлы, отличные от folder3/. Есть также вложенные файлы, поэтому соответствующие подкаталоги также должны быть скопированы

Есть ли одна команда, которая поможет мне? Я могу получить полный список запущенных измененных файлов:

rsync -rcnC --out-format="%f" folder1/ folder2/

Но у rsync, похоже, нет возможности "экспортировать" эти файлы в другой целевой каталог. Могу ли я передать список в cp или какую-нибудь другую программу, чтобы файлы копировались, а каталоги тоже создавались? Например, я пытался

rsync -rcnC --out-format="%f" folder1/ folder2/ | xargs cp -t folder3/

но это также не сохранит каталоги, просто скопирует все файлы в folder3 /

3 ответа

Решение

Используйте --compare-dest.

Со страницы руководства:

--compare-dest = DIR - эта опция указывает rsync использовать DIR на целевом компьютере в качестве дополнительной иерархии для сравнения файлов назначения с выполнением передач (если файлы отсутствуют в каталоге назначения). Если в DIR найден файл, идентичный файлу отправителя, файл НЕ будет перенесен в каталог назначения. Это полезно для создания разреженной резервной копии только тех файлов, которые изменились по сравнению с более ранней резервной копией.

сначала проверьте ваш синтаксис с помощью --dry-run

rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/

Затем, когда вы удовлетворены результатом:

rsync -aHxv --progress  --compare-dest=folder2/ folder1/ folder3/

эта ссылка имеет хорошее объяснение области действия --compare-dest.

Этот маленький скрипт должен работать:

folder1="firsts_folder/"
folder2="second_folder/"
folder3="target_folder"
for x in `rsync -rcnC --out-format="%n"  $folder1 $folder2`
    do
        if [ -d "$folder1/$x" ]; then
            mkdir -p "$folder3/$x"
        else
            cp -frv $folder1/$x $folder3/$x
        fi
done

Но я также думаю, что анализ вывода diff -qr был бы лучшим решением, потому что он дает вам путь и имя для каждого файла последовательно.

РЕДАКТИРОВАТЬ

Это будет одна команда, ваша команда слегка изменена. Но это создаст folder1 под folder3, И он не работает с полными путями, но и скрипт выше не работает с полными путями.

rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/

я использовал \" в rsync заставить его работать с файлами и каталогами, содержащими пробелы. Проверено на Ubuntu 10.04. Надеюсь, поможет.

rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/

Это самая простая форма, которую я могу придумать, если вы готовы сначала спуститься в folder1 перед выдачей команды.

Это более медленный вариант, но я считаю, что он соответствует вашим требованиям и может быть выполнен с использованием не относительных имен каталогов:

rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/

Я оставил ваш оригинал rsync одна команда, потому что вы сказали, что она дает вам правильный список файлов (и мои тестовые файлы, очевидно, отличаются от ваших, поэтому я не мог с уверенностью сказать, что получу правильный список файлов, если я с ним запутался).

grep есть ли удалить имена каталогов из вывода rsync,

Выход из grep затем передается другому rsync с помощью xargs, В парам folder1/./{} дополнительный ./ используется для указания rsync на создание относительных каталогов, начинающихся с ./{}, игнорируя folder1/, Другими словами, это избегает создания folder3/folder1/,

Я смог проверить это только на CentOS 6.4, но AFAIK должен работать так же, как в Ubuntu 12.04.

РЕДАКТИРОВАТЬ: Я должен отметить, что ответ Смитянь, несомненно, лучше, но я хотел бы попытаться сделать это с вашим оригиналом rsync команда в такте, так как он давал вам желаемый результат.

Другие вопросы по тегам