J'ai besoin de supprimer tous les dossiers d'un dossier à l'aide d'un script quotidien. Le dossier de ce jour doit être laissé.
Le dossier 'myfolder' a 3 sous-dossiers: 'test1', 'test2' et 'test3' Je dois tout supprimer sauf 'test2'.
J'essaie de faire correspondre le nom exact ici:
find /home/myfolder -type d ! -name 'test2' | xargs rm -rf
OR
find /home/myfolder -type d ! -name 'test2' -delete
Cette commande essaie toujours de supprimer le dossier principal "mon dossier" également! Y a-t-il un moyen d'éviter cela?
Cela supprimera tous les dossiers à l'intérieur de ./myfolder
Sauf que ./myfolder/test2
Et tout son contenu seront conservés:
find ./myfolder -mindepth 1 ! -regex '^./myfolder/test2\(/.*\)?' -delete
find
démarre une commande find../myfolder
Indique à find de commencer par le répertoire ./myfolder
Et son contenu.
-mindepth 1
Ne correspond pas à ./myfolder
Lui-même, juste les fichiers et répertoires sous-jacents.
! -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 ou (b) à rien du tout.
-delete
Indique à find de supprimer les fichiers correspondants (c'est-à-dire non exclus).
Considérez 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 exécuter 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
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
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.
En utilisant -mindepth 1
s'assurera que le répertoire top 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
va pas éviter les sous-répertoires à l'intérieur 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 n'utilisez pas delete
, car cela implique depth
et cela commencera à s'effacer 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
Utilisez soit rm -rf
(supprimez 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'il y a à l'intérieur) (supprimez echo
pour réellement effacer):
$ find ./myfolder -mindepth 1 -maxdepth 1 -type d -not -name test2 -exec echo rm -rf '{}' \;
rm -rf ./myfolder/test
UNE -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
Si vous utilisez zsh, vous pouvez:
setopt extended_glob # if you don't have it enabled
rm -rf myfolder/^test2
Testé avec la commande ci-dessous et cela a bien fonctionné
find /home/myfolder -maxdepth 1 -type d ! -iname test2 -exec rm -rvf {} \;