Comment supprimer tous les répertoires .svn de mes répertoires d'application

194

L'une des missions d'un outil d'export que j'ai dans mon application, est de nettoyer tous les .svnrépertoires de l'arborescence des répertoires de mon application. Je recherche une commande récursive dans le shell Linux qui traversera l'arborescence entière et supprimera les .svnfichiers.

Je n'utilise pas l'exportation, car ce script sera utilisé pour certains autres noms de fichiers / répertoires qui ne sont pas liés à SVN. J'ai essayé quelque chose comme:

find . -name .svn | rm -fr

Ça n'a pas marché ...

Itay Moav -Malimovka
la source
3
Votre commande devrait fonctionner si vous utilisez 'xargs rm -rf'
Peter van der Heijden
1
Vous pouvez également modifier la commande de suppression "rm -rfi" juste pour vous assurer que vous êtes certain de vouloir supprimer les répertoires.
bedwyr
N'utilisez pas xargs cependant ... vous aurez des problèmes avec les répertoires contenant des espaces, etc. Utilisez find comme décrit ci-dessous.
John Hunt

Réponses:

441

Essaye ça:

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

Avant d'exécuter une commande comme celle-ci, j'aime souvent l'exécuter en premier:

find . -name .svn -exec ls '{}' \;
Greg
la source
43
Vous devrez peut-être mettre {} entre guillemets simples s'il peut y avoir de l'espace ou de tels caractères dans les répertoires: find . -name .svn -exec rm -rf '{}' \;
mtoloo
39
Ce test fonctionne mieux dans mon bash:find . -name .svn -exec echo {} \;
Fedir RYKHTIK
6
Lancer echo / ls en premier est la touche «pro» de cette réponse. N'importe quel imbécile peut détruire un système.
John Hunt
6
que fait le {} \;?
Jon Mitten
3
En exécutant la deuxième commande y compris ls, j'obtiens la entries prop-base props text-base tmpsortie ...
Rasoul
51

Ce que vous avez écrit envoie une liste de noms de fichiers (et de chemins) séparés par une nouvelle ligne rm, mais rm ne sait pas quoi faire avec cette entrée. Il n'attend que des paramètres de ligne de commande.

xargs prend des entrées, généralement séparées par des retours à la ligne, et les place sur la ligne de commande, donc l'ajout de xargs fait fonctionner ce que vous aviez:

find . -name .svn | xargs rm -fr

xargsest suffisamment intelligent pour ne transmettre que le nombre d'arguments rmqu'il peut accepter. Ainsi, si vous aviez un million de fichiers, il pourrait s'exécuter rm1 000 000/65 000 fois (si votre shell pouvait accepter 65 002 arguments sur la ligne de commande {65k fichiers + 1 pour rm + 1 pour -fr}).

Comme des personnes l'ont habilement souligné, les éléments suivants fonctionnent également:

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

Les deux premiers -execformulaires appellent tous les deux rmpour chaque dossier en cours de suppression, donc si vous aviez 1 000 000 de dossiers, rmils seraient appelés 1 000 000 fois. C'est certainement loin d'être idéal. Les nouvelles implémentations de rmvous permettent de conclure la commande avec un +indicateur qui rmacceptera autant d'arguments que possible:

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

La dernière version de find / xargs utilise print0, ce qui permet à find de générer une sortie qui l'utilise \0comme terminateur plutôt que comme nouvelle ligne. Puisque les systèmes POSIX autorisent n'importe quel caractère sauf \0dans le nom de fichier, c'est vraiment le moyen le plus sûr de s'assurer que les arguments sont correctement passés à rmou à l'application en cours d'exécution.

De plus, il y a un -execdirqui s'exécutera à rmpartir du répertoire dans lequel le fichier a été trouvé, plutôt que dans le répertoire de base et un -depthqui démarrera en premier.

Kaleb Pederson
la source
31

Pas besoin de tubes, xargs, exec ou quoi que ce soit:

find . -name .svn -delete

Edit: Je plaisante, -deleteappelle évidemment unlinkat()sous le capot, donc il se comporte comme unlinkou rmdiret refusera de fonctionner sur des répertoires contenant des fichiers.

UN B
la source
54
Un problème, -deletene touchera pas un répertoire s'il contient des fichiers.
Xeoncross
2
Il n'y a pas d' -forceindicateur ou d'indicateur récursif pour le -deleteprédicat, donc cette réponse est inutile. Ainsi, il est de retour à |xargs rm -rf, ce qui est moins laide à taper alors -execavec ses espaces réservés laid et Virgule: -exec rm -rf '{}' \;.
Tomasz Gandor
13

Il existe déjà de nombreuses réponses pour supprimer le répertoire .svn. Mais je tiens à ajouter que vous pouvez éviter ces répertoires dès le début, si vous effectuez une exportation au lieu d'une extraction:

svn export <url>
Mnementh
la source
+1, il n'est pas nécessaire de refaire cela quand il est déjà intégré à svn.
Powerlord
1
Le seul problème que je vois avec cette approche est si vous souhaitez conserver les fichiers non versionnés dans l'exportation. À partir de la documentation svn, "Toutes les modifications locales seront conservées, mais les fichiers non sous contrôle de version ne seront pas copiés."
raidfive
@raidfive: Habituellement, je préfère avoir tous les fichiers pertinents sous contrôle de version, même les bibliothèques utilisées, pour que le projet fonctionne immédiatement. Les fichiers non versionnés dans cette configuration sont des binaires compilés, qui sont refaits par un objectif dans le fichier de construction. Mais vous avez raison, si votre projet repose sur des fichiers qui ne sont pas sous contrôle de version, une exportation ne fonctionnerait pas.
Mnementh
mais ... j'avais besoin d'une réponse plus générale. Le .svn n'était que l'exemple le plus courant, je l'ai noté dans la question.
Itay Moav -Malimovka
12

Si vous n'aimez pas voir beaucoup de

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

avertissements, puis utilisez le -depthcommutateur:

find . -depth -name .svn -exec rm -fr {} \;
paresseux1
la source
10

Sous Windows, vous pouvez utiliser le script de registre suivant pour ajouter «Supprimer les dossiers SVN» à votre menu contextuel de clic droit. Exécutez-le sur n'importe quel répertoire contenant ces fichiers embêtants.

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
la source
Astuce. Pas utile pour l'OP, mais +1 parce que j'ai été impressionné!
rrhartjr
C'est génial. Merci. je sais que c'est super vieux, mais peu importe. je l'aime quand même.
Anthony
9

Vous l'avez presque eu. Si vous voulez passer la sortie d'une commande en tant que paramètres à une autre, vous devrez utiliser xargs. L'ajout -print0garantit que le script peut gérer les chemins avec des espaces:

find . -type d -name .svn -print0|xargs -0 rm -rf
soulmerge
la source
2
pour une certaine résonance, ce qui fonctionnait éventuellement était de trouver. -name .svn | xargs rm -rf Votre version m'a cependant donné la direction, merci
Itay Moav -Malimovka
4
find . -name .svn |xargs rm -rf
Itay Moav -Malimovka
la source
4

En tant que problème important, lorsque vous souhaitez utiliser le shell pour supprimer les dossiers .svn, vous avez besoin de l' argument -depth pour empêcher la commande find d'entrer dans le répertoire qui vient d'être supprimé et d'afficher des messages d'erreur tels que

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

En conséquence, vous pouvez utiliser la commande find comme ci-dessous:

cd [dir_to_delete_svn_folders]
find . -depth -name .svn -exec rm -fr {} \;
fatihk
la source
C'est ce que je cherchais et devrait être la bonne réponse.
luckytaxi
3

Essaye ça:

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

En savoir plus sur la commande find sur developerWorks .

Edward Dale
la source
2

Sinon, si vous souhaitez exporter une copie sans modifier la copie de travail, vous pouvez utiliser rsync:

rsync -a --exclude .svn path/to/working/copy path/to/export
Pimlottc
la source
1
Ou utilisez svn export / path / to / repository, qui fait essentiellement la même chose.
Kaleb Pederson
L'auteur a spécifiquement dit qu'il ne voulait pas utiliser svn; peut-être que son environnement cible n'a pas installé svn.
pimlottc