web-dev-qa-db-fra.com

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

Mon répertoire de niveau supérieur est data. data inclut plusieurs répertoires et ces répertoires ont des sous-répertoires. Je dois supprimer tous les fichiers et répertoires de data/ à l'exception de plusieurs fichiers dans certains répertoires.

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

Exemple:

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

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

11
deepblue

Comme vous l'avez déjà découvert, vous pouvez utiliser la fonction extglob qui est 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'abord avec echo. Cet exemple correspond à tout élément à l'intérieur de 100/ qui n'est pas a.txt ou b.txt et tout élément à l'intérieur de 101/ qui n'est pas c.txt ou d.txt. Si les mêmes règles pour 100/ s'appliquent également à 102/, vous pouvez le faire par exemple:

10[02]/!([ab].txt) # or
{100,102}/!([ab].txt)
12
dessert

Vous pouvez utiliser find pour cela. Vous pouvez annuler les tests dans find avec -not ou !. Cela exclura les correspondances plutôt que de les trouver.

Veillez à ne supprimer aucun des répertoires parents des fichiers que vous souhaitez conserver, en particulier le répertoire en cours., assurez-vous donc de lire attentivement le résultat avant de le supprimer.

Sur la base de votre exemple, vous pourriez faire quelque chose comme ceci à partir du répertoire data.

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

Ajoutez un ! -path ./path/to/dir pour tout chemin que vous souhaitez éviter de supprimer. Vous pouvez utiliser des métacaractères tels que *, mais veillez à bien citer l'expression, par exemple "./path*dir", afin d'éviter toute expansion non souhaitée.

find est récursif par défaut. Même si nous ne trouvons pas ./100 ici, nous retrouverons tout son contenu, à moins qu’ils ne correspondent 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.txt ou b.txt ou foo, mais tous les autres fichiers seront trouvés.

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
7
Zanna