Soluzione 1:
Usa --compare-dest.
Dalla pagina man:
--compare-dest=DIR -Questa opzione indica a rsync di utilizzare DIR sulla macchina di destinazione come gerarchia aggiuntiva per confrontare i file di destinazione con i trasferimenti (se i file mancano nella directory di destinazione). Se nella DIR viene trovato un file identico al file del mittente, il file NON verrà trasferito nella directory di destinazione. Questo è utile per creare un backup sparse dei soli file che sono stati modificati da un backup precedente.
prima controlla la tua sintassi con --dry-run
rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/
Quindi, una volta che sei soddisfatto dell'output:
rsync -aHxv --progress --compare-dest=folder2/ folder1/ folder3/
questo collegamento ha una buona spiegazione dell'ambito --compare-dest.
Soluzione 2:
Questo piccolo script dovrebbe funzionare:
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
Ma penso anche che l'analisi dell'output di diff -qr sarebbe una soluzione migliore perché ti fornisce il percorso e il nome di ogni file in modo coerente.
MODIFICA
Questo sarebbe un comando, il tuo comando leggermente modificato. Ma creerà folder1
sotto il folder3
. E non funziona con percorsi completi ma anche lo script sopra non funziona con percorsi completi.
rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/
Ho usato \"
in rsync
per farlo funzionare con file e directory contenenti spazi vuoti. Testato su Ubuntu 10.04. Spero ti sia d'aiuto.
Soluzione 3:
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/
Questa è la forma più semplice che potrei trovare, se sei disposto a scendere prima in folder1
prima di emettere il comando.
Questo è il più lento opzione, ma credo che soddisfi i tuoi requisiti e potrebbe essere eseguito utilizzando nomi di directory non relativi:
rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/
Ho lasciato il tuo rsync
originale comando da solo, perché hai detto che ti stava dando l'elenco di file corretto (e i miei file di test sono ovviamente diversi dai tuoi, quindi non potrei dire con certezza che avrei ottenuto l'elenco di file corretto se lo avessi incasinato).
Il grep
serve per rimuovere i nomi delle directory dall'output di rsync
.
L'output di grep
viene quindi reindirizzato a un altro rsync
utilizzando xargs
. Nel parametro folder1/./{}
il ./
in più è usato per dire a rsync di creare le relative directory che iniziano con ./{}
, ignorando folder1/
. In altre parole, evita di creare folder3/folder1/
.
Sono stato in grado di testarlo solo su CentOS 6.4, ma AFAIK dovrebbe funzionare allo stesso modo in Ubuntu 12.04.
MODIFICA: Dovrei notare che smithian la risposta di è senza dubbio migliore, ma volevo provare a farlo con il tuo rsync
originale comando intatto poiché ti dava l'output desiderato.