Je sais qu'il y a beaucoup de réponses à vos questions sur la suppression de tous les fichiers avec ou sans une certaine chaîne dans leurs noms, ainsi que des explications sur la suppression de tous les sous-dossiers avec une certaine chaîne dans leurs noms.
Pourtant, il n'y a pas de questions sur la façon de supprimer tous les sous-dossiers sans une certaine chaîne dans leurs noms.
Donc, comme j'ai récemment rencontré un tel problème, y at-il une commande rapide qui aidera à cette situation? Un script bash serait également suffisant.
EDIT:
Par sous-dossiers, je ne parlais que des sous-dossiers de premier niveau, car je ne souhaite pas supprimer les sous-dossiers de deuxième ou troisième niveau, qui peuvent avoir des noms sans la chaîne, des sous-dossiers de premier niveau avec la ficelle.
Supposons que vous souhaitiez démarrer find
dans le répertoire actuel et limitez-le au premier niveau de sous-répertoires:
find . -maxdepth 1
La commande find
a un indicateur utile -not
(ou !
) qui annule le test suivant. Donc, afin de trouver un nom qui contient pas contient une sous-chaîne, ajoutez
-not -name "*substring*"
IMPORTANT: vous voudrez également exclure le répertoire actuel. Sinon, tout le répertoire en cours serait supprimé.
-not -name "."
Ensuite, vous voulez tester uniquement les répertoires:
-type d
Et, si tout va bien, vous voulez supprimer ces répertoires:
-exec rm -rf {} \;
qui dit "pour tous les répertoires trouvés, exécutez cette commande". Le {}
est un espace réservé pour le nom du répertoire (y compris le chemin complet, donc il fonctionne sur le bon). \;
indique la fin de la commande à exécuter.
Résumant:
find . -maxdepth 1 -not -name "*substring*" -not -name "." -type d -exec rm -rf {} \;
devrait marcher. Mais d’abord, essayez-le sans la partie -exec
.
Les opérateurs extended glob du bash shell peuvent effectuer la négation de modèle, par exemple. donné
$ tree .
.
├── subdir
│ ├── other file
│ └── somefile
├── subdirbar
│ ├── other file
│ └── somefile
├── subdirbaz
│ ├── other file
│ └── somefile
└── subdirfoo
├── other file
└── somefile
4 directories, 8 files
puis, si l'extension étendue est activée (shopt -s extglob
)
$ rm -rf !(*foo*)
supprime (récursivement) tous les répertoires de niveau supérieur ne contenant pas la chaîne foo
, en laissant
$ tree
.
└── subdirfoo
├── other file
└── somefile
1 directory, 2 files
Cependant, cela supprime également les fichiers dont les noms ne contiennent pas foo
au niveau supérieur. Les globs étendus AFAIK bash ne peuvent pas distinguer les fichiers des répertoires - mais zsh fournit qualificatifs de glob, qui permettent, par exemple, de donné
% tree
.
├── foofile
├── other file
├── somefile
├── subdir
│ ├── other file
│ └── somefile
├── subdirbar
│ ├── other file
│ └── somefile
├── subdirbaz
│ ├── other file
│ └── somefile
└── subdirfoo
├── other file
└── somefile
4 directories, 11 files
puis dans zsh
% setopt EXTENDED_GLOB
% ls -d (^(*foo*))
other file somefile subdir subdirbar subdirbaz
alors que l'ajout du qualificatif de répertoire (/)
% ls -d (^(*foo*))(/)
subdir subdirbar subdirbaz
alors
% rm -rf (^(*foo*))(/)
supprime uniquement répertoires dont les noms n'incluent pas la chaîne foo
, en laissant les fichiers non modifiés intacts.
% tree
.
├── foofile
├── other file
├── somefile
└── subdirfoo
├── other file
└── somefile
1 directory, 5 files