Solution 1 :
Utilisez --compare-dest.
À partir de la page de manuel :
--compare-dest=DIR - Cette option indique à rsync d'utiliser DIR sur la machine de destination comme une hiérarchie supplémentaire pour comparer les fichiers de destination aux transferts (si les fichiers manquent dans le répertoire de destination). Si un fichier est trouvé dans DIR qui est identique au fichier de l'expéditeur, le fichier ne sera PAS transféré vers le répertoire de destination. Ceci est utile pour créer une sauvegarde fragmentée des seuls fichiers qui ont été modifiés par rapport à une sauvegarde antérieure.
vérifiez d'abord votre syntaxe avec --dry-run
rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/
Ensuite, une fois que vous êtes satisfait du résultat :
rsync -aHxv --progress --compare-dest=folder2/ folder1/ folder3/
ce lien a une bonne explication de la portée --compare-dest.
Solution 2 :
Ce petit script devrait fonctionner :
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
Mais je pense aussi que l'analyse de la sortie de diff -qr serait une meilleure solution car elle vous donne le chemin et le nom de chaque fichier de manière cohérente.
MODIFIER
Ce serait une commande, votre commande légèrement modifiée. Mais cela créera folder1
sous le folder3
. Et cela ne fonctionne pas avec les chemins complets, mais le script ci-dessus ne fonctionne pas non plus avec les chemins complets.
rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/
J'ai utilisé \"
en rsync
pour le faire fonctionner avec des fichiers et des répertoires contenant des blancs. Testé sur Ubuntu 10.04. J'espère que ça aide.
Solution 3 :
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/
C'est la forme la plus simple que je puisse trouver, si vous êtes prêt à descendre d'abord dans folder1
avant d'émettre la commande.
C'est le plus lent option, mais je pense qu'elle répond à vos besoins et qu'elle pourrait être exécutée en utilisant des noms de répertoires non relatifs :
rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/
J'ai laissé votre rsync
d'origine commande seule, parce que vous avez dit qu'elle vous donnait la bonne liste de fichiers (et mes fichiers de test sont évidemment différents des vôtres, donc je ne peux pas dire avec certitude que j'obtiendrais la bonne liste de fichiers si je la dérangeais).
Le grep
est là pour supprimer les noms de répertoire de la sortie de rsync
.
La sortie de grep
est ensuite redirigé vers un autre rsync
en utilisant xargs
. Dans le paramètre folder1/./{}
le ./
supplémentaire est utilisé pour indiquer à rsync de créer les répertoires relatifs commençant par ./{}
, en ignorant folder1/
. En d'autres termes, cela évite de créer folder3/folder1/
.
Je n'ai pu tester cela que sur CentOS 6.4, mais autant que je sache, cela devrait fonctionner de la même manière dans Ubuntu 12.04.
MODIF : Je dois noter que forgeron La réponse de est sans aucun doute meilleure, mais je voulais essayer de le faire avec votre rsync
d'origine commande intacte puisqu'elle vous donnait le résultat souhaité.