Non c'è bisogno di pipe, xargs, exec o altro:
find . -name .svn -delete
Modifica: Scherzo, evidentemente -delete
chiama unlinkat()
sotto il cofano, quindi si comporta come unlink
o rmdir
e si rifiuterà di operare su directory contenenti file.
Ciò che hai scritto invia un elenco di nomi di file (e percorsi) separati da una nuova riga a rm
, ma rm non sa cosa fare con quell'input. Aspetta solo i parametri della riga di comando.
xargs
prende l'input, solitamente separato da nuove righe, e lo inserisce nella 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 tanti argomenti a rm
come può accettare. Pertanto, se avessi un milione di file, potrebbe eseguire rm
1.000.000/65.000 volte (se la tua shell può accettare 65.002 argomenti sulla riga di comando {65k file + 1 per rm + 1 per -fr}).
Come le persone hanno abilmente sottolineato, anche quanto segue funziona:
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
entrambe le forme chiamano rm
per ogni cartella eliminata, quindi se avevi 1.000.000 di cartelle, rm
sarebbe invocato 1.000.000 di volte. Questo è certamente meno che ideale. Implementazioni più recenti di rm
ti permettono di concludere il comando con un +
indicando che rm
accetterà quanti più argomenti possibile:
find . -name .svn -exec rm -rf {} +
L'ultima versione di find/xargs usa print0, che fa in modo che find generi un output che usa \0
come terminatore piuttosto che come newline. Poiché i sistemi POSIX consentono qualsiasi carattere tranne \0
nel nome del file, questo è davvero il modo più sicuro per assicurarsi che gli argomenti vengano passati correttamente a rm
o l'applicazione in esecuzione.
Inoltre, c'è un -execdir
che eseguirà rm
dalla directory in cui è stato trovato il file, piuttosto che dalla directory di base e da un -depth
che inizierà prima la profondità.
Prova questo:
find . -name .svn -exec rm -rf '{}' \;
Prima di eseguire un comando del genere, spesso mi piace eseguire prima questo:
find . -name .svn -exec ls '{}' \;