Come rimuovere tutte le directory .svn dalle mie directory dell'applicazione


193

Una delle missioni di uno strumento di esportazione che ho nella mia applicazione è quella di pulire tutte le .svndirectory dalla mia struttura di directory dell'applicazione. Sto cercando un comando ricorsivo nella shell Linux che attraverserà l'intero albero ed eliminerà i .svnfile.

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

find . -name .svn | rm -fr

Non ha funzionato ...


3
Il tuo comando dovrebbe funzionare se usi 'xargs rm -rf'
Peter van der Heijden,

1
Potresti anche voler modificare il comando di cancellazione "rm -rfi" solo per essere sicuro di voler eliminare le directory.
bedwyr,

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

Risposte:


439

Prova questo:

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

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

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

43
Potrebbe essere necessario inserire {} tra virgolette singole se ci potrebbe essere spazio o tali caratteri nelle directory: find . -name .svn -exec rm -rf '{}' \;
mtoloo

38
Questo test funziona meglio nella mia bash:find . -name .svn -exec echo {} \;
Fedir RYKHTIK

6
Eseguire echo / ls per primo è il tocco 'pro' di questa risposta. Qualsiasi sciocco può distruggere un sistema.
John Hunt,

6
cosa fa {} \;?
Jon Mitten,

3
Eseguendo il secondo comando incluso ls, ottengo entries prop-base props text-base tmpoutput ...
Rasoul,

51

Quello che hai scritto invia un elenco di nomi (e percorsi) di file separati da una nuova riga rm, ma rm non sa cosa fare con quell'input. Si aspetta solo parametri dalla riga di comando.

xargs accetta input, generalmente separati da newline, e li posiziona sulla riga di comando, quindi l'aggiunta di xargs fa funzionare ciò che avevi:

find . -name .svn | xargs rm -fr

xargsè abbastanza intelligente da passare solo quanti più argomenti rmpuò accettare. Quindi, se avessi un milione di file, potrebbe essere eseguito rm1.000.000 / 65.000 volte (se la tua shell potesse accettare 65.002 argomenti sulla riga di comando {65k file + 1 per rm + 1 per -fr}).

Come hanno sottolineato abilmente le persone, anche i seguenti funzionano:

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 -execmoduli richiedono entrambi rmche ogni cartella venga eliminata, quindi se tu avessi 1.000.000 di cartelle, rmverrebbero invocate 1.000.000 di volte. Questo è sicuramente meno che ideale. Le implementazioni più recenti rmti consentono di concludere il comando con un +indicatore che rmaccetterà il maggior numero di argomenti possibile:

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

L'ultima versione di find / xargs utilizza print0, il che rende find generare output che utilizza \0come terminatore anziché una nuova riga. Poiché i sistemi POSIX consentono qualsiasi carattere tranne \0il nome file, questo è davvero il modo più sicuro per assicurarsi che gli argomenti siano passati correttamente rmo l'applicazione in esecuzione.

Inoltre, c'è un file -execdirche verrà eseguito rmdalla directory in cui è stato trovato il file, piuttosto che dalla directory di base e -depthche inizierà prima in profondità.


31

Non c'è bisogno di pipe, xargs, exec o altro:

find . -name .svn -delete

Modifica: sto scherzando, evidentemente -deletechiama unlinkat()sotto il cofano, quindi si comporta come unlinko rmdire rifiuterà di operare su directory contenenti file.


54
Un problema, -deletenon toccherà una directory se contiene file.
Xeoncross,

2
Non esiste un -forceflag ricorsivo o per -deletepredicato, quindi questa risposta è inutile. Così, si torna in |xargs rm -rf, che è meno brutto di digitare poi -execcon i suoi brutti segnaposto e virgola: -exec rm -rf '{}' \;.
Tomasz Gandor,

13

Ci sono già molte risposte fornite per cancellare la directory .svn. Ma voglio aggiungere, che puoi evitare queste directory dall'inizio, se fai un'esportazione anziché un checkout:

svn export <url>

+1, non è necessario rifarlo quando è già incorporato in svn.
Powerlord,

1
L'unico problema che vedo con questo approccio è se si desidera conservare i file non esaminati nell'esportazione. Dai documenti svn, "Tutte le modifiche locali verranno conservate, ma i file che non sono sotto il controllo della versione non verranno copiati".
raidfive del

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

ma ... avevo bisogno di una risposta più generalista. Il .svn era solo l'esempio più comune, l'ho notato nella domanda.
Itay Moav -Malimovka,

12

Se non ti piace vedere molto

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

avvisi, quindi utilizzare l' -depthinterruttore:

find . -depth -name .svn -exec rm -fr {} \;

10

In Windows, è possibile utilizzare il seguente script di registro per aggiungere "Elimina cartelle SVN" al menu contestuale 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\" \""

Trucco pulito. Non utile per l'OP, ma +1 perché sono stato colpito!
rrhartjr,

Questo e spettacolare. Grazie. so che questo è super vecchio, ma comunque. lo adoro comunque.
Anthony

9

Ce l'hai quasi fatta. Se si desidera passare l'output di un comando come parametri a un altro, è necessario utilizzare xargs. L'aggiunta -print0assicura che lo script sia in grado di gestire percorsi con spazi bianchi:

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

2
per un po 'di risonanza ciò che alla fine ha funzionato è stato trovato. -name .svn | xargs rm -rf La tua versione mi ha dato la direzione però, grazie
Itay Moav -Malimovka


4

Come problema importante, quando si desidera utilizzare la shell per eliminare le cartelle .svn È necessario l' argomento -depth per impedire al comando find di accedere alla directory che è stata appena eliminata e che mostra messaggi di errore come ad es.

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

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

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

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


2

In alternativa, se si desidera 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.
Kaleb Pederson,

L'autore ha affermato espressamente di non voler usare svn; forse nel suo ambiente di destinazione non è installato svn.
pimlottc,
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.