rsync una lista de directorios con ruta absoluta en el archivo de texto

9

Tengo un archivo de texto que contiene una lista de directorios con su ruta absoluta

$ cat DirectoriesToCopy.txt

/data/Dir1
/data/Dir2

Quiero usar rsync para copiar todos estos directorios conservando su ruta absoluta a otra ubicación.

Intenté el siguiente comando rsync, pero no funciona

rsync -avr --include-from=DirectoriesToCopy.txt --exclude='*/' --exclude='/*'  /  /media/MyDestination/

¿Qué está mal aquí?

indiajoe
fuente
¿Desea transferir /data/Dir1e /data/Dir2incluir sus contenidos a /media/MyDestination/Dir1y /media/MyDestination/Dir2? ¿O quieres incluir la /dataparte? ¿Qué tan grande es esta lista? ¿Es demasiado grande para simplemente enumerar esas entradas en la línea de comando? De todos modos, sus --excludedeclaraciones evitan la recurrencia.
wurtel
Quiero transferir todos los archivos dentro de esos directorios también. Hay muchos archivos en ese directorio, por lo que me gustaría evitar crear otro archivo de texto con todos los nombres de archivo.
indiajoe
Me gustaría mantener mi camino completo como /media/MyDestination/data/Dir2/. Agregué --exclude para evitar que se copien otros directorios y archivos en /.
indiajoe
En los casos en que la lista de directorios no es muy grande, supongo que la siguiente opción es más fácilrsync -av $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe

Respuestas:

6

Use el siguiente comando:

rsync -av --include-from=DirectoriesToCopy.txt --include /data/ --exclude='/data/*' --exclude='/*/' / /media/MyDestination/

Debe incluir / data / explícitamente, también podría haberlo agregado a la lista en el archivo. Luego excluya todos los demás directorios (el orden es importante con incluye / excluye).

Tenga en cuenta que su uso de -rera redundante, ya que está incluido en -a.

EDITAR: También podría lograr el mismo resultado con:

rsync -av --relative /data/Dir1 /data/Dir2 /media/MyDestination/

No es rsync lo que te obliga a hacer cosas difíciles solo para copiar un par de directorios, solo te brinda múltiples formas de hacer lo mismo; en algunos casos, la opción de incluir / excluir puede ser más adecuada, aquí haría lo --relativo anterior (sin --relativeque termine con , /media/MyDestination/Dir1y /media/MyDestination/Dir2con --relativetoda la ruta de origen copiada al destino).

wurtel
fuente
Gracias que funcionó. Estoy un poco sorprendido de que uno tenga que definir una secuencia de filtros tan cuidadosa para simplemente copiar una lista de directorios usando rsync. Por ejemplo, si mi lista de directorios no estaba en un directorio / datos / común, sino que se distribuía en muchas ubicaciones, los filtros para definir se vuelven bastante complicados.
indiajoe
Ver mi edición a mi respuesta.
wurtel
Gracias. Entonces, si mi lista de directorios no es muy grande, podría usar el indicador relativo como se muestra a continuación. rsync -av --relative $(cat DirectotiesToCopy.txt) /media/MyDestination/
indiajoe
Si; tener en cuenta --relativees solo otra opción.
wurtel
7

Quiero usar rsync para copiar todos estos directorios [de una lista] conservando su ruta absoluta a otra ubicación

No use --includeni --filtervariaciones, ya que eso solo confundirá las cosas. En cambio, use --files-from=_filename_. (Si lo hace, asegúrese de hacer muchas pruebas).

  1. Cree la lista de directorios en un archivo, un directorio / archivo por línea.

  2. Use rsync's --files-from=con el archivo de arriba.

  3. Use la opción --relative/ -Rpara asegurarse de que los nombres de ruta de origen se copien al final del destino.

  4. Incluso si tiene la -aopción, también incluya -r. Desde la página del manual:

    En ambos casos, si la opción -r estaba habilitada, la jerarquía completa de ese directorio también se transferiría (tenga en cuenta que -r debe especificarse explícitamente con --files-from, ya que no está implícito en -a).

Comando completo:

rsync ${DEBUG:+-nv} -arR --files-from=<list_of_files.txt> <top-level-dir>  <target-dir>

(los archivos en list_of_files.txt deben ser relativos o encontrarse en el directorio de nivel superior )

(si DEBUG está configurado, rsync simplemente imprime lo que podría haberse copiado).

Oteo
fuente
1
¡Esto es lo que necesitaba! Sin embargo, "--include-from" debería ser "--files-from". También usé "--list-only" para ver una vista previa de lo que RSYNC hará antes de dejar que funcione.
Adambean
1
Gracias, he actualizado la respuesta. --include-fromtambién funcionará, pero lo que dije sobre -res en gran medida irrelevante.
Oteo
2

El manual de rsync advierte sobre este escenario (sección "Incluir / excluir reglas de patrón"):

esto no funcionará:

+ /some/path/this-file-will-not-be-found
+ /file-is-included
- *

Esto falla porque el directorio principal "some"está excluido por la '*'regla, por lo que rsync nunca visita ninguno de los archivos en los directorios "some"o "some/path". Una solución es solicitar que se incluyan todos los directorios en la jerarquía mediante el uso de una sola regla: "+ */"(colóquela en algún lugar antes de la "- *"regla) y tal vez use la --prune-empty-dirsopción Otra solución es agregar reglas de inclusión específicas para todos los directorios principales que deben visitarse. Por ejemplo, este conjunto de reglas funciona bien:

+ /some/
+ /some/path/
+ /some/path/this-file-is-found
+ /file-also-included
- *

En su caso, creo que el enfoque más sencillo sería para preprocesar la lista de directorios para incluir de manera que cada vez que incluyes /path/to/foo, que también incluyen todos los directorios padre ( /path/to, /path, /), y también incluyen los subdirectorios de los directorios originales ( /path/to/foo/***), y después de todo esto tiene una regla que excluye todo lo que no se haya enumerado anteriormente ( *).

<DirectoriesToCopy.txt awk '
    {print "+ " $0 "/***"; while (sub(/\/+[^\/]+\/*$/, "/")) print "+ " $0}
    END {print "- *"}
' >rsync-rules.txt
rsync -avr --include-from=rsync-rules.txt  /  /media/MyDestination/
Gilles 'SO- deja de ser malvado'
fuente
Gracias por la explicación detallada y el script para crear el archivo de reglas. Entiendo el problema ahora. Todavía siento que hubiera sido bueno para rsync tener una opción como --dirs-from = DirectoriosToCopy.txt como un atajo a todos los filtros complicados.
indiajoe