Cómo eliminar todos los directorios .svn de mis directorios de aplicaciones

192

Una de las misiones de una herramienta de exportación que tengo en mi aplicación es limpiar todos los .svndirectorios del árbol de directorios de mi aplicación. Estoy buscando un comando recursivo en el shell de Linux que atraviese todo el árbol y elimine los .svnarchivos.

No estoy usando exportar, ya que este script se usará para otros nombres de archivo / directorio que no están relacionados con SVN. Intenté algo como:

find . -name .svn | rm -fr

No funcionó ...

Itay Moav -Malimovka
fuente
3
Su comando debería funcionar si usa 'xargs rm -rf'
Peter van der Heijden
1
También es posible que desee modificar el comando de eliminación "rm -rfi" solo para asegurarse de que está seguro de que desea eliminar los directorios.
bedwyr
Sin embargo, no use xargs ... tendrá problemas con los directorios que tienen espacios, etc. Use find como se describe a continuación.
John Hunt el

Respuestas:

438

Prueba esto:

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

Antes de ejecutar un comando como ese, a menudo me gusta ejecutar esto primero:

find . -name .svn -exec ls '{}' \;
Greg
fuente
43
Es posible que tenga que poner {} en la comilla simple si puede haber espacio o dichos caracteres en los directorios: find . -name .svn -exec rm -rf '{}' \;
mtoloo
38
Esta prueba funciona mejor en mi fiesta:find . -name .svn -exec echo {} \;
Fedir RYKHTIK
66
Ejecutar echo / ls primero es el toque 'profesional' para esta respuesta. Cualquier tonto puede destruir un sistema.
John Hunt
66
lo que hace el {} \;hacer?
Jon Mitten
3
Al ejecutar el segundo comando incluido ls, obtengo entries prop-base props text-base tmpresultados ...
Rasoul
51

Lo que escribió envía una lista de nombres de archivo separados por nueva línea (y rutas) rm, pero rm no sabe qué hacer con esa entrada. Solo espera parámetros de línea de comando.

xargs toma datos, generalmente separados por líneas nuevas, y los coloca en la línea de comando, por lo que agregar xargs hace que lo que haya funcionado

find . -name .svn | xargs rm -fr

xargses lo suficientemente inteligente como para pasarle tantos argumentos rmcomo pueda aceptar. Por lo tanto, si tuviera un millón de archivos, podría ejecutarse rm1,000,000 / 65,000 veces (si su shell pudiera aceptar 65,002 argumentos en la línea de comando {65k archivos + 1 para rm + 1 para -fr}).

Como las personas han señalado con destreza, lo siguiente también funciona:

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

Los dos primeros -execformularios requieren rmque se elimine cada carpeta, por lo que si tuviera 1,000,000 de carpetas, rmse invocaría 1,000,000 de veces. Esto es ciertamente menos que ideal. Las implementaciones más recientes de le rmpermiten concluir el comando con una +indicación que rmaceptará tantos argumentos como sea posible:

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

La última versión de find / xargs usa print0, lo que hace que find genere una salida que se usa \0como un terminador en lugar de una nueva línea. Dado que los sistemas POSIX permiten cualquier carácter excepto \0en el nombre del archivo, esta es realmente la forma más segura de asegurarse de que los argumentos se pasen correctamente a rmla aplicación o se ejecute.

Además, hay una -execdirque se ejecutará rmdesde el directorio en el que se encontró el archivo, en lugar de hacerlo en el directorio base y una -depthque comenzará primero en profundidad.

Kaleb Pederson
fuente
31

No hay necesidad de tuberías, xargs, exec ni nada:

find . -name .svn -delete

Editar: es broma, evidentemente -deletellama unlinkat()bajo el capó, por lo que se comporta como unlinko rmdiry se negará a operar en directorios que contengan archivos.

AB
fuente
54
Un problema, -deleteno tocará un directorio si contiene archivos.
Xeoncross
2
No hay un -forceindicador recursivo para el -deletepredicado, por lo que esta respuesta es inútil. Por lo tanto, es hora de volver a |xargs rm -rf, que es menos feo que escribir a continuación, -execcon sus feas marcadores de posición y coma: -exec rm -rf '{}' \;.
Tomasz Gandor
13

Ya hay muchas respuestas proporcionadas para eliminar el directorio .svn. Pero quiero agregar, que puede evitar estos directorios desde el principio, si realiza una exportación en lugar de un pago:

svn export <url>
Mnementh
fuente
+1, no hay necesidad de rehacer esto cuando ya está integrado en svn.
Powerlord
1
El único problema que veo con este enfoque es si desea conservar los archivos no versionados en la exportación. De los documentos de svn, "todos los cambios locales se conservarán, pero los archivos que no estén bajo el control de versión no se copiarán".
Raidfive
@raidfive: por lo general, prefiero tener todos los archivos relevantes bajo el control de versiones, incluso las bibliotecas utilizadas, para que el proyecto funcione de inmediato. Los archivos no versionados en esta configuración son archivos binarios compilados, que se rehacen por un objetivo en el archivo de compilación. Pero tiene razón, si su proyecto se basa en archivos que no están bajo control de versión, una exportación no funcionaría.
Mnementh
pero ... necesitaba una respuesta más generalista. El .svn fue solo el ejemplo más común, lo noté en la pregunta.
Itay Moav -Malimovka
12

Si no te gusta ver mucho

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

advertencias, luego use el -depthinterruptor:

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

En Windows, puede usar el siguiente script de registro para agregar "Eliminar carpetas SVN" al menú contextual del botón derecho. Ejecútelo en cualquier directorio que contenga esos molestos archivos.

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\" \""
Nathan Taylor
fuente
Buen truco. No es útil para el OP, pero +1 porque me impresionó.
rrhartjr
Esto es asombroso. Gracias. Sé que esto es muy viejo, pero lo que sea. Me encanta de todos modos.
Anthony
9

Casi lo tienes. Si desea pasar la salida de un comando como parámetros a otro, deberá usar xargs. Agregar -print0asegura que el script pueda manejar rutas con espacios en blanco:

find . -type d -name .svn -print0|xargs -0 rm -rf
soulmerge
fuente
2
por alguna resonancia lo que funcionó eventualmente fue encontrar. -name .svn | xargs rm -rf Sin embargo, tu versión me dio la dirección, gracias
Itay Moav -Malimovka
4
find . -name .svn |xargs rm -rf
Itay Moav -Malimovka
fuente
4

Como un problema importante, cuando desea utilizar shell para eliminar carpetas .svn, necesita un argumento de profundidad para evitar que el comando find entre al directorio que acaba de eliminar y muestre mensajes de error como, por ejemplo,

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

Como resultado, puede usar el comando de búsqueda como a continuación:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
fatihk
fuente
Esto es lo que estaba buscando y debería ser la respuesta correcta.
luckytaxi
3

Prueba esto:

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

Lea más sobre el comando find en developerWorks .

Edward Dale
fuente
2

Alternativamente, si desea exportar una copia sin modificar la copia de trabajo, puede usar rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export
pimlottc
fuente
1
O use svn export / path / to / repository, que esencialmente hace lo mismo.
Kaleb Pederson
El autor dijo específicamente que no quería usar svn; tal vez su entorno de destino no tenga instalado svn.
pimlottc