Copia tutti i file e le cartelle esclusi i file e le cartelle di sovversione su OS X


14

Sto cercando di copiare tutti i file e le cartelle da una directory all'altra, ma escludo determinati file. In particolare, voglio escludere file e cartelle di sovversione. Tuttavia, vorrei una soluzione generale ma concisa.

Immagino che troverò la necessità di escludere diversi tipi di file nel prossimo futuro. Ad esempio, potrei voler escludere .svn, * .bak e * .prj.

Ecco cosa ho messo insieme così, ma non funziona per me. La prima parte, trova le opere, ma sto facendo qualcosa di sbagliato in xargs e cp . Ho provato cp con e senza il -R. Inoltre, sto usando OS X e sembra avere una versione meno funzionante di xargs rispetto ai sistemi Linux.

find ./sourcedirectory -not \( -name .svn -a -prune \)
     | xargs -IFILES cp -R FILES ./destinationdirectory

Potrei sbagliarmi, ma penso che sia più complicato di quanto pensi. Anche se il findcomando viene utilizzato correttamente -pruneper escludere gli elementi .svn, si passa quindi il -Rflag a cpcui si dice che quel comando è ricorsivo. Quando lo fa, perdi la granularità che hai avuto nel findcomando. Ho intenzione di armeggiare con questo per un minuto, ma penso che la risposta non sia usare -Rnel cpcomando.
Telemaco,

Sembra funzionare per me su un sistema Linux. Puoi essere più specifico su cosa significa "non funziona"? Qualche messaggio di errore? I file vengono / non vengono copiati come previsto?
In pausa fino a ulteriore avviso.

È la -Rbandiera, ne sono abbastanza sicuro. Rimuovilo e dovresti stare bene (anche se potresti voler aggiungere -mindepth 1per ignorare la cartella della directory di livello superiore che non vuoi copiare, suppongo)
Telemaco,

Di solito faccio queste cose copiando tutto e quindi eliminando i file indesiderati nelle directory di destinazione. Questo è spesso molto più semplice.
Jan Doggen,

Risposte:


22

(Modificato dopo aver riletto la domanda. Il questionario dice che rsync non è installato)

Un possibile problema con la soluzione find / xargs sono gli spazi nei nomi dei file. Per ovviare a questo, dire a find e xargs di usare un carattere null (ASCII 0) per separare i file trovati:

find ./sourcedirectory -not ( -name .svn -a -prune ) -print0 | xargs -0 -IFILES cp FILES ./destinationdirectory

Se scopri che rsync è disponibile, penso ancora che rsync sia la soluzione di gran lunga migliore:

Usa rsync con l'opzione -C. Dalla pagina man di rsync :

Questa è una scorciatoia utile per escludere una vasta gamma di file che spesso non si desidera trasferire tra i sistemi. Utilizza un algoritmo simile a CVS per determinare se un file deve essere ignorato.

Questo dirà a rsync di ignorare questi schemi:

RCS SCCS CVS CVS.adm RCSLOG cvslog.* tags TAGS .make.state .nse_depinfo *~
#* .#* ,* _$* *$ *.old *.bak *.BAK *.orig *.rej .del-* *.a *.olb *.o *.obj 
*.so *.exe *.Z *.elc *.ln core .svn/ .git/ .bzr/

Per esempio:

rsync -avC /path/to/source/directory /path/to/destination/directory

(nota: se non hai ancora familiarità con rsync, assicurati di leggere in quella pagina man su come rsync gestisce una barra finale nel percorso di origine. Si comporta in modo diverso se includi la barra rispetto a se non lo fai. Cerca 'barra finale')


Oh ratti, ho appena riletto la tua domanda e ho visto che hai detto che non hai installato rsync. Sul mio MacBook Pro (OS X 10.6.1) è in / usr / bin / rsync. È stato installato anche per me sotto Tiger (10.4) e Leopard (10.5).
Doug Harris,

Sono abbastanza sicuro che tu (e l'OP) non desideri la -Rbandiera nella xargsparte del comando.
Telemaco,

Buona cattura, l'ho copiato dalla domanda originale. Modificherà ora.
Doug Harris,

1
Grazie Doug! Una cosa che predico "usa lo strumento giusto per il lavoro". Di recente vengo dal mondo Windows a OSX e sto ancora armeggiando nell'ignoranza. Ho pubblicato la stessa domanda in un canale Linux e qualcuno ha rapidamente detto, basta usare "rsynch" Ho digitato "rsynch" nel terminale e ho visto che non esisteva e ho continuato a indagare sulla ricerca | approccio xargs. Sono un po 'testardo in quel modo. Ad ogni modo, OSX ha "rsync" per impostazione predefinita e il tuo post è stato molto utile. Non ho ancora abbastanza esperienza qui per sapere quale è meglio, ma rsync è sicuramente molto più conciso. Grazie!
Michael Prescott,

Se farai qualche lavoro con macchine linux oltre al tuo lavoro su OS X, penso che valga la pena dedicare il tuo tempo a imparare come usare rsync. La sua funzionalità principale è la copia intelligente delle cose cambiate (come robocopy su Windows, se hai familiarità con quello). Poiché copia solo il delta, è un ottimo modo per gestire backup (non Time Machine), distribuzioni di codice e simili.
Doug Harris,

2

Non soluzioni generali ma ... puoi usare il comando svn export per creare una copia dell'area di lavoro senza le cartelle dei metadati .svn.


Non essere offensivo, ma non sono sicuro del motivo per cui questa risposta è stata votata. Sono consapevole delle capacità di svn, ma "Vorrei una soluzione generale ma concisa. Immagino che troverò la necessità di escludere diversi tipi di file nel prossimo futuro"
Michael Prescott,

2
%> mkdir -p FOLDER_OUT && ( tar cf - FOLDER_OR_FILES_IN --exclude=.svn  | tar xvf - -C FOLDER_OUT )

se vuoi puoi anche inserire 'pv' o qualcosa di simile tra i 2 processi tar.


2

Un modo sporco ma rapido e conciso:

cp -r source destination
find destination -iname .svn |xargs rm -rf

Questo copia una directory in un'altra (quindi l'opzione ricorsiva -r) e quindi cancella in modo ricorsivo tutto ciò che viene chiamato .svn(ignorando il caso).


1

Lo farei diversamente, usando tar e il suo meccanismo di esclusione.

Da nella directory di destinazione:

tar -X excludefile -C source -f - . | tar xf -

Questo eseguirà il cd alla fonte, eseguirà il taring dei contenuti, escludendo ciò che è elencato in excludefile, e quindi decomprimilo nella directory corrente.


Soluzione elegante davvero.
Nick Stinemates,

bene, è la stessa risposta che ho dato, poco dopo. inoltre devi essere nella directory di destinazione ... :)
Akira,

0

Risposta modificata : il problema è che -Rrende la copia ricorsiva e quindi si finisce per copiare i file nascosti. Ecco cosa vorrei usare:

find source/  -mindepth 1 -not \( -name .svn -prune \) | xargs -Iitem cp item target/

Il -mindepth 1flag dice finddi ignorare la directory di livello superiore. Dato che vuoi copiare tutto il contenuto di quella directory in una nuova directory di livello superiore, suppongo che non lo desideri.

Come dice Chris Nava nella sua risposta , c'è già un modo integrato per farlo se stiamo parlando di cartelle SVN, ma poiché hai chiesto una soluzione più generale, questo potrebbe aiutare un po '.


Grazie Telemaco, è utile. Non ho esperienza da criticare, ma ripeterò ciò che mi è stato detto dal mio post originale. "xargs is broken" Il commentatore irc sconosciuto che mi ha detto che mi ha ispirato a guardarmi un po 'di più e penso che la risposta di Doug Harris risolva il problema. Ciò dice a xargs di usare caratteri null. Penso che sia l'opzione -0?
Michael Prescott,

@Michael: xargsnon è rotto, ma su sistemi simili a Unix, il default non è usare nomi di file (o nomi di directory) con spazi all'interno. Se hai spazi o caratteri "divertenti" nei tuoi nomi di file (o nomi di directory), allora devi fare un lavoro extra per affrontarlo. (In GNU find, c'è un'intera sezione nella manpagina chiamata "FILENAMI INUSUALI" a causa di questo problema.) La -0bandiera xargse -print0per findaiutare a gestire questi problemi. Ti prometto, tuttavia, che non vuoi usare -Rnel tuo comando di copia. Annullerà qualsiasi cosa tu faccia per evitare le directory SVN.
Telemaco,

0

Suppongo che dipenda da quanto è grande il tuo albero, ma perché non copiare prima tutto , quindi tagliare le cartelle .svn dopo:

find /dest-dir -type d -name .svn -exec rm -rf {} \;

?


Senza alcun benchmark, il mio pensiero iniziale è che questo è un doppio spreco di cicli della CPU: la copia e la rimozione. Potrebbe volerci un po 'di tempo umano in più per creare il findcomando giusto , ma lo fai solo una volta. Puoi usare il comando centinaia di volte, una volta che hai capito bene.
Telemaco,

@Telemachus - vero, ma è quello in cui i computer sono (presumibilmente) bravi - fanno le cose difficili quindi non dobbiamo! Davvero - che male c'è nel copiare alcuni file solo per averli cancellati subito dopo, se ciò significa che i comandi che inventi a farlo sono molto semplici?
Steve Folly,

@Steve: non c'è niente di male, davvero. Per quanto va, questa è un'ottima soluzione. Segue un principio che mi piace: "Fai la cosa più semplice possibile che funzioni". D'altra parte, viola un altro principio che mi piace ancora di più: "Impara i tuoi strumenti". Preferirei imparare ad usare findmeglio se stesso, in modo da non doverlo fare. Ma hai ragione: non c'è niente di veramente sbagliato in questa soluzione.
Telemaco,

@Telemachus: concordo con "Impara i tuoi strumenti". Quando ho iniziato, sono sicuro che il mio comando di ricerca sopra mi sarebbe sembrato molto criptico allora :-)
Steve Folly,


0

Puoi anche fare il contrario. Copia tutto quindi elimina le cartelle .svn usando il comando seguente:

find . | grep ".svn" | xargs rm -rf
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.