J'ai le même problème que cette question Comment supprimer tous les fichiers/dossiers du dossier sauf quelques dossiers? plusieurs fois. C'est la raison pour laquelle j'ai voulu écrire moi-même un script pour une commande rmnot. Cela devrait prendre un nombre arbitraire de fichiers, même avec des caractères génériques si nécessaire, et supprimer tout (pas recursevely) dans le même répertoire à l'exception de ces fichiers. Exemple typique serait:
rmnot *tex *bib *png
Mon script fonctionne, mais étant donné que je suis inexpérimenté et que je veux l'apprendre correctement, existe-t-il un moyen plus élégant d'écrire ce script?
#!/bin/zsh
insert="-name . -or -name .."
for i in {1..$#}; do
insert="$insert -or -name ${(P)i}"
done
insert="\( $insert \)"
eval "find -not $insert -exec rm {} \;"
PS: Je dois utiliser ZSH à cause de la double substitution ${(P)i}
toute autre solution fonctionnerait également en bash, je pense.
====== Version optimisée =====
#!/bin/bash
insert="-name . -or -name .."
for i; do
insert="$insert -or -name $i"
done
insert="\( $insert \)"
find -maxdepth 1 -not $insert -delete
Vous n'avez même pas besoin d'un script. Si vous utilisez bash, vous pouvez activer extglob
et donner des motifs négatifs:
$ ls
foo.avi foo.bbl foo.bib foo.log foo.png foo.tex foo.txt foo.wav
$ shopt -s extglob
$ rm !(*tex|*bib|*png)
$ ls
foo.bib foo.png foo.tex
Comme expliqué dans man bash
:
If the extglob Shell option is enabled using the shopt builtin, several
extended pattern matching operators are recognized. In the following
description, a pattern-list is a list of one or more patterns separated
by a |. Composite patterns may be formed using one or more of the fol‐
lowing sub-patterns:
?(pattern-list)
Matches zero or one occurrence of the given patterns
*(pattern-list)
Matches zero or more occurrences of the given patterns
+(pattern-list)
Matches one or more occurrences of the given patterns
@(pattern-list)
Matches one of the given patterns
!(pattern-list)
Matches anything except one of the given patterns
Avec zsh
, l'équivalent est:
setopt extended_glob
rm ^(*tex|*bib|*png)
Si vous voulez toujours écrire un script pour cela, concaténez simplement les arguments que vous lui donnez, mais n'utilisez pas de caractères génériques (*
), laissez le script les ajouter (merci à @Helios d'avoir suggéré une version plus simple):
#!/usr/bin/env bash
## Iterate over the arguments
for i
do
## Add them to the pattern to be excluded
pat+="*$i|"
done
## Activate extglob
shopt -s extglob
## Delete non-matching files
rm !(${pat})