Solución 1:
Utilice --comparar-destino.
Desde la página del manual:
--compare-dest=DIR -Esta opción le indica a rsync que use DIR en la máquina de destino como una jerarquía adicional para comparar los archivos de destino con las transferencias (si faltan archivos en el directorio de destino). Si se encuentra un archivo en DIR que es idéntico al archivo del remitente, el archivo NO se transferirá al directorio de destino. Esto es útil para crear una copia de seguridad escasa de solo archivos que han cambiado desde una copia de seguridad anterior.
primero verifique su sintaxis con --dry-run
rsync -aHxv --progress --dry-run --compare-dest=folder2/ folder1/ folder3/
Luego, una vez que esté satisfecho con el resultado:
rsync -aHxv --progress --compare-dest=folder2/ folder1/ folder3/
este enlace tiene una buena explicación de --compare-dest scope.
Solución 2:
Este pequeño script debería funcionar:
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
Pero también creo que analizar la salida de diff -qr sería una mejor solución porque le brinda la ruta y el nombre de cada archivo de manera consistente.
EDITAR
Este sería un comando, su comando ligeramente modificado. Pero creará folder1
bajo el folder3
. Y no funciona con rutas completas, pero el script anterior tampoco funciona con rutas completas.
rsync -rcnC --out-format="\"%f\"" folder1/ folder2/ | xargs cp --parents -rfvt folder3/
Usé \"
en rsync
para que funcione con archivos y directorios que contengan espacios en blanco. Probado en Ubuntu 10.04. Espero que ayude.
Solución 3:
rsync -rcnC --out-format="%f" . ../folder2/ |xargs cp --parents -rt ../folder3/
Esa es la forma más simple que se me ocurrió, si está dispuesto a descender primero a folder1
antes de emitir el comando.
Este es el más lento opción, pero creo que cumple con sus requisitos, y podría ejecutarse utilizando nombres de directorio no relativos:
rsync -rcnC --out-format="%n" folder1/ folder2/ |grep -vP "/$" |xargs -I{} rsync -R folder1/./{} folder3/
Dejé tu rsync
original comando solo, porque dijiste que te estaba dando la lista de archivos correcta (y mis archivos de prueba son obviamente diferentes a los tuyos, por lo que no podría decir con certeza que obtendría la lista de archivos correcta si me metía con ella).
El grep
está ahí para eliminar nombres de directorios de la salida de rsync
.
La salida de grep
luego se canaliza a otro rsync
usando xargs
. En el parámetro folder1/./{}
el ./
adicional se usa para decirle a rsync que cree los directorios relativos que comienzan con ./{}
, ignorando folder1/
. En otras palabras, evita crear folder3/folder1/
.
Solo pude probar esto en CentOS 6.4, pero AFAIK debería funcionar igual en Ubuntu 12.04.
EDITAR: Debo señalar que smithian La respuesta de es indudablemente mejor, pero quería intentar hacerlo con su rsync
original comando intacto ya que le estaba dando el resultado deseado.