Exclusion de certains fichiers et répertoires lors de la suppression de fichiers

11

Mon répertoire de niveau supérieur est data. datacomprend plusieurs répertoires et ces répertoires ont des sous-répertoires. J'ai besoin de supprimer tous les fichiers et répertoires à l'intérieur, data/sauf plusieurs fichiers dans certains répertoires.

Par exemple, les données incluent les répertoires 100et 101. Je veux juste garder a.txtet les b.txtfichiers 100/et c.txtet les d.txtfichiers 101/tout en supprimant tous les autres fichiers et répertoires 100et 101.

Exemple:

.
├── 100
   ├── a.txt
   ├── b.txt
   ├── c.txt
   └── d.txt
└── 101
    ├── a.txt
    ├── b.txt
    ├── c.txt
    └── d.txt

J'utilise la rm -rf !(a.txt|b.txt)commande mais je ne peux pas appliquer cette commande automatiquement pour chaque répertoire.

bleu profond
la source

Réponses:

12

Comme vous l'avez déjà découvert, vous pouvez utiliser la extglobfonctionnalité activée avec:

shopt -s extglob

Cela permet d'exclure des correspondances afin que vous puissiez faire des choses comme:

rm 100/!([ab].txt) 101/!([cd].txt)

C'est une bonne idée de le tester d' echoabord. Cet exemple correspondra à tout ce 100/qui n'est pas a.txtou à l' b.txtintérieur et à tout ce 101/qui n'est pas c.txtou d.txt. Si les mêmes règles 100/s'appliquent 102/également, vous pouvez par exemple:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
dessert
la source
Je viens de donner un exemple pour les répertoires 100 et 101 mais en réalité le nombre de sous-répertoires est près de 20. Existe-t-il un moyen d'implémenter le code ci-dessus pour chaque répertoire sans écrire chaque nom de répertoire dans le dossier principal?
deepblue
@deepblue Veuillez fournir un exemple exact de cela dans votre question ( modifier ), il est particulièrement difficile de savoir comment rmsavoir quels fichiers conserver dans quels répertoires si vous ne souhaitez pas le spécifier.
dessert le
7

Vous pouvez l'utiliser findpour cela. Vous pouvez annuler les tests findavec -notou !. Cela exclura les correspondances, plutôt que de les trouver.

Vous devez faire attention à ne supprimer aucun des répertoires parents des fichiers que vous souhaitez conserver, en particulier le répertoire actuel . , assurez-vous donc de lire attentivement la sortie avant de supprimer.

Sur la base de votre exemple, vous pouvez faire quelque chose comme ça depuis le datarépertoire.

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt"

Ajoutez un ! -path ./path/to/dirpour tout chemin que vous souhaitez éviter de supprimer. Vous pouvez utiliser des métacaractères comme *, mais assurez-vous de citer l'expression si vous le faites, par exemple "./path*dir", pour empêcher toute expansion indésirable.

findest récursif par défaut. Même si nous ne le trouvons pas ./100ici, nous trouverons tout son contenu à moins qu'il ne corresponde au modèle [ab].txt. Si vous ne pouvez pas faire correspondre tous les noms que vous souhaitez conserver, ajoutez un autre test:

! -path "./100/[ab].txt" ! -path ./100/foo

Cela ne trouvera pas a.txtou b.txtou foo, mais il trouvera tous les autres fichiers.

Lorsque vous êtes sûr de voir ce que vous voulez, vous pouvez ajouter -deleteà la fin pour supprimer les fichiers trouvés:

find ! -path . ! -path ./100 ! -path ./101 ! -path "./100/[ab].txt" ! -path "./101/[cd].txt" -delete
Zanna
la source