Сравнить 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
команда в такте, так как он давал вам желаемый результат.