2009-08-18 10 views
177

Una delle missioni di uno strumento di esportazione che ho nella mia applicazione è quella di pulire tutte le directory .svn dall'albero della directory delle applicazioni. Sto cercando un comando ricorsivo nella shell di Linux che attraverserà l'intero albero ed eliminerà i file .svn.Come rimuovere tutte le directory .svn dalle directory delle mie applicazioni

Non sto utilizzando l'esportazione, poiché questo script verrà utilizzato per altri nomi di file/directory che non sono correlati a SVN. Ho provato qualcosa di simile:

find . -name .svn | rm -fr 

Non ha funzionato ...

+3

Il comando dovrebbe funzionare se si utilizza 'xargs rm -rf' –

+1

Si potrebbe anche voler modificare il comando di cancellazione "rm -rfi "solo per essere sicuro di voler eliminare le directory. – bedwyr

+0

Non usare xargs però .. avrai problemi con le directory che contengono spazi in esse, ecc. Usa find come descritto di seguito. –

risposta

408

Prova questo:

find . -name .svn -exec rm -rf '{}' \; 

Prima di eseguire un comando del genere, spesso mi piace correre questo primo:

find . -name .svn -exec ls '{}' \; 
+43

Potrebbe essere necessario mettere {} in virgolette singole se ci può essere spazio o tali caratteri nelle directory: 'trova. -name .svn -exec rm -rf '{}' \; ' – mtoloo

+36

Questo test funziona meglio nella mia bash:' find. -name .svn -exec echo {} \; ' –

+4

L'esecuzione di echo/ls è il tocco" pro "di questa risposta. Qualsiasi pazzo può distruggere un sistema. –

9

È quasi avuto. Se si desidera passare l'output di un comando come parametri a un altro, è necessario utilizzare xargs. L'aggiunta di -print0 si assicura lo script in grado di gestire i percorsi con spazi:

find . -type d -name .svn -print0|xargs -0 rm -rf 
+2

per alcuni reson che cosa ha funzionato è stato trovato. -name .svn | xargs rm -rf La tua versione mi ha dato la direzione, grazie –

+0

questo funziona in fish shell sotto osx – mcuadros

3

Prova questa:

find . -name .svn -exec rm -v {} \; 

Leggi di più riguardo il comando find a developerWorks.

11

Se non ti piace vedere un sacco di

find: `./.svn': No such file or directory 

avvisi, quindi utilizzare lo switch -depth:

find . -depth -name .svn -exec rm -fr {} \; 
4
find . -name .svn |xargs rm -rf 
2

In alternativa, se si vuole esportare una copia senza modificare la copia di lavoro, è possibile utilizzare rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export 
+1

Oppure usa svn export/path/to/repository, che essenzialmente fa la stessa cosa. –

+0

L'autore ha detto in particolare che non voleva usare svn; forse il suo ambiente di destinazione non ha installato svn. – pimlottc

50

Quello che hai scritto invia un elenco di nuova riga separata nomi dei file (e percorsi) a rm, ma rm non sa cosa fare con quell'input. Si aspetta solo i parametri della riga di comando.

xargs riceve l'input, di solito separate da ritorni a capo, e li pone sulla linea di comando, quindi l'aggiunta di xargs rende ciò che si aveva lavoro:

find . -name .svn | xargs rm -fr 

xargs è abbastanza intelligente che passerà solo come molti argomenti per rm come può accettare. Quindi, se avessi un milione di file, potrebbe essere eseguito rm 1.000.000/65.000 volte (se la tua shell potrebbe accettare 65.002 argomenti nella riga di comando {65k file + 1 per rm + 1 per -fr}).

Come persone hanno abilmente fatto notare, i seguenti lavori anche:

find . -name .svn -exec rm -rf {} \; 
find . -depth -name .svn -exec rm -fr {} \; 
find . -type d -name .svn -print0|xargs -0 rm -rf 

I primi due -exec forme sia chiamare rm per ogni cartella di essere eliminati, quindi se avete avuto 1.000.000 cartelle, rm sarebbe invocata 1.000.000 volte .Questo è certamente meno che ideale. Più recenti implementazioni di rm consentono di concludere il comando con un + che indica che rm accetteranno il maggior numero di argomenti possibili:

find . -name .svn -exec rm -rf {} + 

dell'ultima ricerca/xargs versione utilizza print0, il che rende trovare generare un output che utilizza \0 come terminatore piuttosto che una nuova riga. Poiché i sistemi POSIX consentono qualsiasi carattere tranne \0 nel nome file, questo è veramente il modo più sicuro per assicurarsi che gli argomenti vengano passati correttamente a rm o all'applicazione in esecuzione.

Inoltre, c'è un -execdir che eseguirà rm dalla directory in cui è stato trovato il file, piuttosto che alla directory di base e di un -depth che inizierà la profondità prima.

+2

Upvote solo perché stai usando xargs. – Augusto

9

In Windows, è possibile utilizzare il seguente script del Registro di sistema per aggiungere "Elimina cartelle SVN" al menu di scelta rapida del tasto destro. Eseguilo su qualsiasi directory contenente quei file fastidiosi.

Windows Registry Editor Version 5.00 

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN] 
@="Delete SVN Folders" 

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Folder\shell\DeleteSVN\command] 
@="cmd.exe /c \"TITLE Removing SVN Folders in %1 && COLOR 9A && FOR /r \"%1\" %%f IN (.svn) DO RD /s /q \"%%f\" \"" 
+0

Trucchi Neat. Non utile per l'OP, ma +1 perché sono rimasto colpito! – rrhartjr

+0

questo è fantastico. Grazie. so che è super vecchio, ma qualunque cosa. lo adoro comunque. – Anthony

31

Non c'è bisogno di tubi, xargs, exec, o qualsiasi cosa:

find . -name .svn -delete 

Modifica: Sto scherzando, evidentemente -delete chiamate unlinkat() sotto il cofano, quindi si comporta come unlink o rmdir e volontà rifiutare di operare su directory contenenti file.

+0

bello. Grazie. non era a conoscenza dell'argomento '-delete' –

+52

Un problema,' -delete' non toccherà una directory se contiene file. – Xeoncross

+2

Non c'è nessun flag '-force' o ricorsivo per il predicato' -delete', quindi questa risposta è inutile. Quindi, torna a '| xargs rm -rf', che è meno brutto da digitare quindi' -exec' con i suoi brutti segnaposti e punto e virgola: '-exec rm -rf '{}' \;'. –

11

Esistono già molte risposte per l'eliminazione della directory .svn. Ma voglio aggiungere, che si può evitare queste directory fin dall'inizio, se si fa un export al posto di un checkout:

svn export <url> 
+0

+1, non è necessario ripristinarlo quando è già integrato in svn. – Powerlord

+1

L'unico problema che vedo con questo approccio è se si desidera conservare file non verificati nell'esportazione. Da svn docs, "Tutte le modifiche locali verranno mantenute, ma i file che non sono sotto controllo di versione non verranno copiati." – raidfive

+0

@raidfive: in genere preferisco avere tutti i file rilevanti sotto controllo di versione, anche le librerie usate, in modo che il progetto funzioni immediatamente. I file non supervisionati in questa configurazione sono binari compilati, che sono rifatti da un obiettivo nel file build. Ma hai ragione, se il tuo progetto si basa su file non sotto controllo di versione, un'esportazione non funzionerebbe. – Mnementh

4

Come una questione importante, quando si desidera utilizzare shell eliminare svn cartelle È necessario l'argomento -depth per impedire che il comando find inserisca la directory appena cancellata e che mostri i messaggi di errore come ad es.

"find: ./.svn: No such file or directory" 

Di conseguenza, è possibile utilizzare il comando trovare come di seguito:

cd [dir_to_delete_svn_folders] 
find . -depth -name .svn -exec rm -fr {} \; 
+0

Questo è quello che stavo cercando e dovrebbe essere la risposta corretta. – luckytaxi

Problemi correlati