15 votos

¿Cómo cp archivo y crear directorio si no existe?

Quiero copiar archivos modificados en un repositorio svn a otro directorio, manteniendo su estructura de directorios.

Después de leer la página man de awk y xargs encuentro una forma de obtener los nombres de los archivos modificados de esta manera:

$ svn status -q | awk '{ print $2 }' | xargs -d \\n -I '{}' cp '{}' /tmp/xen/

Pero el problema es que de esta manera no se conservan las estructuras de los directorios, quiero copiar los archivos así:

./common/superp.c -> /tmp/xen/common/superp.c
./common/m2mgr.c -> /tmp/xen/common/m2mgr.c
./common/page_alloc.c -> /tmp/xen/common/page_alloc.c
./arch/x86/mm.c -> /tmp/xen/arch/x86/mm.c
./arch/x86/mm/shadow/private.h -> /tmp/xen/arch/x86/mm/shadow/private.h

He intentado cambiar el comando cp por cp '{}' /tmp/xen/'{}' pero dice que no existe tal archivo o directorio. ¿Hay alguna manera de hacer que cp copie el archivo y cree el directorio si es necesario? Y por favor, señale si esta cadena de comandos puede ser simplificada. :-)

Gracias por todas vuestras respuestas. Como el directorio es un poco grande, no quiero copiar todo el directorio usando cp -R o rsync. La sugerencia de CK de utilizar una tubería tar es bastante útil.

svn status -q | awk '{ print $2 }' | xargs tar cf -  | (cd /tmp/xen/; tar xvf -)

12voto

CK. Puntos 923

Un par de reflexiones rápidas:

  • Añadir en un mkdir -p $(dirname FILE)
  • ¿Podría usar una pipa de alquitrán para ordenar todo?

Editar

 tar -cf archive.tar  `svn status -q | awk '{print $2}'`

Debe crear un archivo con los ficheros modificados. Entonces:

  tar -xf archive.tar -C /tmp/xen

debe ponerlo donde quiera. Si tiene que ser en un solo paso, también es posible.

4voto

Kyle Brandt Puntos 50907

rsync simplifica mucho las cosas, es la herramienta que suelo utilizar para copiar estructuras de directorios enteras:

rsync -av /home/source/svn/repo /home/dest/svn/

Esto creará el directorio repo y todo su contenido en el directorio /home/dest/svn, por lo que tendrá /home/dest/svn/repo/...

Así que para su ejemplo:

rsync -rv ./ /tmp/xen/

-a, conservaría las marcas de tiempo y sería recursivo entre otras cosas, 'man rsync'.

Actualización después de darme cuenta de que leí mal la pregunta:

Para imitar la estructura de directorios (alternativa al tar):

rsync -av --include='*/' --exclude='*' source destination

Y luego para copiar los archivos antes de, digamos, hace 20 minutos:

find . -type f -mmin -20 -print0 | xargs -0 cp --target-directory /mydestdir/

2voto

Tim Abell Puntos 573

Aquí está esa frase para que sirva de referencia:

svn status -q | awk '{print $2}' | xargs tar -c | tar -xC /tmp/xen

Y en inglés:

  • obtener la lista de archivos de interés con svn status -q que se canaliza en...
  • awk que extrae la columna con las rutas de los archivos: awk '{print $2}'
  • xargs se utiliza para dar la lista de archivos a tar, que a su vez envía un tarball de los archivos a stdout: xargs tar -c
  • que se vuelve a extraer rápidamente ( -x ) en el directorio de destino ( -C path ): tar -xC /tmp/xen

1voto

wazoox Puntos 3514

Usa "dirname" para extraer la ruta "mkdir -p" para crearla, algo así como :

xargs -d \\n -l '{}' mkdir -p \`dirname '{}'\` && cp '{}' /tmp/xen/

1voto

zimon Puntos 11

rsync -a no crea nuevos directorios más profundos que en la profundidad 1, por lo que rsync es sólo una solución parcial y, por ejemplo, no es adecuado para mí (busqué en Google una respuesta a cómo rsync directorios a alguna jerarquía remota cuando varios directorios faltan en el medio)

Editar: Tengo el dir. de origen: /home/usuario/proyectos/tarea/1/1.1/ Y quiero rsyncarlo a remote:/home/user/projects/homework/1/1.1/ ...pero el destino no tiene todavía el directorio /home/usuario/proyectos/tareas ...y no quiero transferir otros subdirectorios en la máquina de origen que están en /home/usuario/proyectos/

Edición2: Encontré una manera, con la opción rsync --relative: El ejemplo anterior iría así:

cd /home/projects/ ; rsync -aR homework/1/1.1 user@remote:/home/user/projects/

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by: