Cela supprimera tous les dossiers à l'intérieur de ./myfolder
sauf que ./myfolder/test2
et tout son contenu sera conservé :
find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
Comment ça marche
find
lance une commande de recherche.-
./myfolder
indique à find de commencer par le répertoire./myfolder
et son contenu. -
-mindepth 1
ne pas correspondre à./myfolder
lui-même, uniquement les fichiers et répertoires qu'il contient. -
! -regex '^./myfolder/test2\(/.*\)?'
indique à find d'exclure (!
) tout fichier ou répertoire correspondant à l'expression régulière^./myfolder/test2\(/.*\)?
.^
correspond au début du nom du chemin. L'expression(/.*\)?
correspond soit (a) à une barre oblique suivie de quoi que ce soit, soit (b) à rien du tout. -
-delete
indique à find de supprimer les fichiers correspondants (c'est-à-dire non exclus).
Exemple
Envisagez une structure de répertoires qui ressemble ;
$ find ./myfolder
./myfolder
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Nous pouvons lancer la commande find (sans -delete
) pour voir à quoi cela correspond :
$ find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?'
./myfolder/test1
./myfolder/test1/dir1
./myfolder/test1/dir1/test2
./myfolder/test1/dir1/test2/file4
./myfolder/test1/file1
./myfolder/test3
./myfolder/test3/file3
Nous pouvons vérifier que cela a fonctionné en regardant les fichiers qui restent :
$ find ./myfolder
./myfolder
./myfolder/test2
./myfolder/test2/file2
./myfolder/test2/dir2
Utilisation de bash :
shopt -s extglob
rm -r myfolder/!(test2)/
Exemple :
$ tree myfolder/
myfolder/
├── test1
│ └── file1
├── test2
│ └── file2
└── test3
└── file3
$ echo rm -r myfolder/!(test2)
rm -r myfolder/test1 myfolder/test3
$ rm -r myfolder/!(test2)
$ tree myfolder/
myfolder/
└── test2
└── file2
1 directory, 1 file
tl;dr
find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 \
-exec echo rm -rf '{}' \;
Supprimez l'écho si vous êtes satisfait de la liste des fichiers.
Utilisation de -mindepth 1
veillera à ce que le haut répertoire n'est pas sélectionné.
$ find ./myfolder -mindepth 1 -type d
./myfolder/test2
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Mais un -not -name test2
ne sera pas éviter les sous-répertoires à l'intérieur de test2
:
$ find ./myfolder -mindepth 1 -type d -not -name 'test2'
./myfolder/test2/one
./myfolder/test2/two
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Pour ce faire, vous avez besoin de quelque chose comme prune :
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test
./myfolder/test/a1
./myfolder/test/a1/a2
./myfolder/test/a1/a2/a3
Mais ne pas utiliser delete
, car cela implique depth
et cela commencera à s'effacer à partir du chemin le plus long :
$ find ./myfolder -depth -mindepth 1 -name test2 -prune -o -type d -print
./myfolder/test/a1/a2/a3
./myfolder/test/a1/a2
./myfolder/test/a1
./myfolder/test
Soit utiliser rm -rf
(supprimer le echo
si vous voulez réellement effacer):
$ find ./myfolder -mindepth 1 -name test2 -prune -o -type d -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
rm -rf ./myfolder/test/a1
rm -rf ./myfolder/test/a1/a2
rm -rf ./myfolder/test/a1/a2/a3
Ou, aussi utilisez maxdepth
si tout ce dont vous avez besoin est de supprimer les répertoires (et tout ce qu'ils contiennent) (supprimez le echo
pour réellement effacer):
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
Un -delete
échouera toujours si le répertoire n'est pas vide :
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -delete
find: cannot delete ‘./myfolder/test’: Directory not empty