L’une des missions d’un outil d’exportation que j’ai dans mon application est de nettoyer tous les répertoires .svn
de l’arborescence de mes répertoires. Je recherche une commande récursive dans le shell Linux qui parcourt l’arborescence complète et supprime les fichiers .svn
.
Je n'utilise pas l'exportation, car ce script sera utilisé pour d'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é ...
Essaye ça:
find . -name .svn -exec rm -rf '{}' \;
Avant d’exécuter une commande comme celle-ci, j’aime souvent exécuter la première:
find . -name .svn -exec ls '{}' \;
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 les entrées, généralement séparées par des lignes, et les place sur la ligne de commande. L'ajout de xargs rend ce que vous aviez déjà fait:
find . -name .svn | xargs rm -fr
xargs
est suffisamment intelligent pour qu'il ne transmette autant d'arguments à rm
qu'il ne peut en accepter. Ainsi, si vous avez un million de fichiers, il peut exécuter rm
1 000 000/65 000 fois (si votre shell peut accepter 65 002 arguments sur la ligne de commande {65k fichiers + 1 pour rm + 1 pour -fr}).
Comme les personnes l’ont bien fait remarquer, les mesures suivantes 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 -exec
forment tous les deux l'appel rm
pour chaque dossier à supprimer. Ainsi, si vous aviez 1 000 000 dossiers, rm
serait invoqué 1 000 000 fois. C'est certainement moins qu'idéal. Les nouvelles implémentations de rm
vous permettent de conclure la commande avec un +
indiquant que rm
acceptera 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 utilisant \0
comme terminateur plutôt que comme une nouvelle ligne. Étant donné que les systèmes POSIX autorisent tout caractère sauf \0
dans le nom du fichier, il s'agit du moyen le plus sûr de s'assurer que les arguments sont correctement passés à rm
ou à l'application en cours d'exécution.
De plus, il existe un -execdir
qui exécutera rm
à partir du répertoire dans lequel le fichier a été trouvé, plutôt que dans le répertoire de base, et un -depth
qui commence par la profondeur en premier.
Pas besoin de pipes, xargs, exec ou quoi que ce soit:
find . -name .svn -delete
Edit: Je plaisante, évidemment -delete
appelle unlinkat()
sous le capot, de sorte qu'il se comporte comme unlink
ou rmdir
et refusera d'opérer sur des répertoires contenant des fichiers.
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>
Si vous n'aimez pas voir beaucoup de
find: `./.svn': No such file or directory
avertissements, utilisez le commutateur -depth
:
find . -depth -name .svn -exec rm -fr {} \;
Vous l'avez presque eu. Si vous souhaitez transmettre la sortie d'une commande en tant que paramètres à une autre, vous devez utiliser xargs. L'ajout de -print0
permet de s'assurer que le script peut gérer les chemins avec des espaces:
find . -type d -name .svn -print0|xargs -0 rm -rf
Sous Windows, vous pouvez utiliser le script de registre suivant pour ajouter "Supprimer les dossiers SVN" à votre menu contextuel par 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\" \""
find . -name .svn |xargs rm -rf
En tant que problème important, lorsque vous souhaitez utiliser Shell pour supprimer des dossiers .svn, vous avez besoin de l'argument - depth pour empêcher la recherche de la commande entrer dans le répertoire qui vient d'être supprimé et afficher des messages d'erreur comme par exemple.
"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 {} \;
Essaye ça:
find . -name .svn -exec rm -v {} \;
En savoir plus sur la commande find sur developerWorks .
Si vous souhaitez exporter une copie sans modifier la copie de travail, vous pouvez également utiliser rsync:
rsync -a --exclude .svn path/to/working/copy path/to/export