Come file cp e creare directory se non esiste?


15

Voglio copiare i file modificati in un repository svn in un'altra directory, mantenendo la loro struttura di directory.

Dopo aver letto la manpage di awk e xargs trovo un modo per cambiare i nomi dei file in questo modo:

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

Ma il problema è che in questo modo le strutture di directory non vengono conservate, voglio copiare file come questo:

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

Ho provato a cambiare il comando cp in cp '{}' / tmp / xen / '{}' ma non è stato detto alcun file o directory. Esiste un modo per creare file di copia cp e creare directory se necessario? E ti preghiamo di sottolineare se questa catena di comandi può essere semplificata. :-)

Grazie per tutte le tue risposte Poiché la directory è un po 'grande, non voglio copiare l'intera directory usando cp -R o rsync. Il suggerimento di CK di usare una pipa per catrame è abbastanza utile.

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

Risposte:


12

Paio di pensieri rapidi:

  • Aggiungi in un mkdir -p $ (dirname FILE)
  • Potresti usare una pipa di catrame per risolvere tutto?

modificare

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

Dovrebbe creare un archivio dei file modificati. Poi:

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

dovresti metterlo dove vuoi. Se deve essere in un solo passaggio, anche questo è possibile.


4

rsync rende piuttosto semplice, è lo strumento che generalmente utilizzo per copiare intere strutture di directory:

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

Questo creerà la directory repo e tutto il suo contenuto nella directory / home / dest / svn, quindi avrai / home / dest / svn / repo / ...

Quindi per te esempio:

rsync -rv ./ /tmp/xen/

-a, preserverebbe i timestamp e sarebbe tra l'altro ricorsivo, "man rsync".

Aggiorna dopo aver realizzato che ho letto la domanda sbagliata:

Per imitare la struttura della directory (alternativa tar):

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

E poi per copiare i file prima di dire 20 minuti fa:

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

È ovvio, ma sincronizzerà tutto, non solo i file modificati, giusto?
CK.

oops, mancato
Kyle Brandt

2

Ecco quel one-liner per riferimento:

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

E in inglese:

  • ottenere l'elenco dei file di interesse con svn status -q, che viene reindirizzato in ...
  • awk che estrae la colonna con i percorsi dei file: awk '{print $2}'
  • xargs è usato per dare alla lista dei file tar, che a sua volta invia un tarball dei file a stdout: xargs tar -c
  • che viene prontamente ri-estratto ( -x) nella directory di destinazione ( -C path):tar -xC /tmp/xen

1

Usa "dirname" per estrarre il percorso "mkdir -p" per crearlo, qualcosa del tipo:

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

1

rsync -a non crea nuove directory più in profondità rispetto alla profondità 1, quindi rsync è solo una soluzione parziale e per esempio non adatta a me (ho cercato su Google di trovare una risposta su come risincronizzare le directory in qualche gerarchia remota quando nel mezzo mancano diverse directory )

Modifica: Voglio dire, ho la directory sorgente: /home/user/projects/homework/1/1.1/ E voglio risincronizzarlo in remoto: /home/user/projects/homework/1/1.1/ ... ma destinazione non ha ancora directory / home / utente / progetti / compiti a casa ... e non voglio trasferire altre sottodirectory nella macchina sorgente che sono in / home / utente / progetti /

Edit2: trovato un modo, con rsync - opzione relativa: l'esempio sopra sarebbe andato così:

cd / home / progetti /; rsync -aR compiti a casa / 1 / 1.1 utente @ telecomando: / home / utente / progetti /


0

Suggerirei quanto segue:

  • copia tutto
  • trova i file non modificati ed eliminali, lasciando i file modificati al loro posto.

A proposito, cp con R flag copia file / cartelle in modo ricorsivo.

cp -R

0
  • costruire la struttura di directory in /tmp/f2per i file in/tmp/f

    $ cd /tmp/f/
    $ find . -type f -exec dirname {} \; | uniq | xargs -I {} mkdir /tmp/f2/{} -p
    
  • copia il file nella nuova destinazione /tmp/f2/

    $ cd /tmp/f
    $ find . -type f -exec cp  {}  /tmp/f2/{} -aPv \;
    
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.