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

15

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

Después de leer la página de manual de awk y xargs, encuentro una manera de cambiar los nombres de archivo 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 directorios, quiero copiar archivos como este:

./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

Intenté cambiar el comando cp a cp '{}' / tmp / xen / '{}' pero no dijo tal archivo o directorio. ¿Hay alguna forma de hacer un archivo de copia cp y crear un directorio si es necesario? Y señale si esta cadena de comandos se puede simplificar. :-)

Gracias por todas sus respuestas. Como el directorio es un poco grande, no quiero copiar todo el directorio usando cp -R o rsync. La sugerencia de CK de usar un tubo de alquitrán es bastante útil.

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

Respuestas:

12

Un par de pensamientos rápidos:

  • Agregue un mkdir -p $ (dirname FILE)
  • ¿Podrías usar un tubo de alquitrán para resolverlo todo?

Editar

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

Debe crear un archivo de los archivos modificados. Luego:

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

deberías ponerlo donde quieras. Si necesita estar en un solo paso, eso también es posible.

CK.
fuente
4

rsync hace que sea bastante simple, es la herramienta que generalmente uso para copiar estructuras de directorios completas:

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 / ...

Entonces, por ejemplo:

rsync -rv ./ /tmp/xen/

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

Actualice después de darme cuenta que leí mal la pregunta:

Para imitar la estructura del directorio (alternativa tar):

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

Y luego copiar los archivos antes de decir hace 20 minutos:

find . -type f -mmin -20 -print0 | xargs -0 cp --target-directory /mydestdir/
Kyle Brandt
fuente
Esa es la obvia, pero eso sincronizará todo, no solo los archivos modificados, ¿verdad?
CK.
Uy, me perdí eso
Kyle Brandt
2

Aquí está esa frase para referencia:

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

Y en ingles:

  • obtener una lista de archivos de interés con svn status -q, que se canaliza a ...
  • awk que extrae la columna con las rutas de archivo: awk '{print $2}'
  • xargs se usa 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
Tim Abell
fuente
1

Use "dirname" para extraer la ruta "mkdir -p" para crearlo, algo así como:

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

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

Editar: Quiero decir, tengo el directorio fuente: /home/user/projects/homework/1/1.1/ Y quiero sincronizarlo con el control remoto: /home/user/projects/homework/1/1.1/ ... pero el destino todavía no tiene el directorio / home / user / projects / homework ... y no quiero transferir otros subdirectorios en la máquina fuente que están en / home / user / projects /

Edit2: Encontrado un camino, con rsync - opción relativa: El ejemplo anterior sería así:

cd / inicio / proyectos /; rsync -aR tarea / 1 / 1.1 usuario @ remoto: / inicio / usuario / proyectos /

zimon
fuente
0

Sugeriría lo siguiente:

  • copia todo
  • encuentre archivos no modificados y elimínelos, dejando los archivos modificados en su lugar.

Por cierto, cp con R flag copia archivos / carpetas de forma recursiva.

cp -R
Karolis T.
fuente
0
  • construir estructura de directorios /tmp/f2para archivos en/tmp/f

    $ cd /tmp/f/
    $ find . -type f -exec dirname {} \; | uniq | xargs -I {} mkdir /tmp/f2/{} -p
    
  • copiar el archivo a un nuevo destino /tmp/f2/

    $ cd /tmp/f
    $ find . -type f -exec cp  {}  /tmp/f2/{} -aPv \;
    
ren8zhu
fuente