Il existe de nombreuses situations où l'utilisation d'un fichier *
est pratiquement inévitable, par exemple rm -rf *
dans un dossier contenant des milliers de sous-dossiers et de fichiers.
Mais que faire si vous souhaitez exclure un ou deux fichiers ou dossiers de la rm
commande? J'ai fait une recherche sur Google et n'ai trouvé que des solutions assez compliquées comme find . -depth -not \( -name 'one' -o -name 'two' \
-o -name 'three' \) -exec rm {} \;
indiqué ici .
Y a-t-il une possibilité de le faire plus facilement - sans ce détour find
? Par exemple, rm -rf --exclude='one' --exclude='two' --exclude='three' *
comme dans rsync ou tout simplement rm -rf -e 'one','two','three' *
?
Peut-être même une possibilité générale d'exclure les choses de *
(si d' autres commandes telles que cp
, mv
... ne pas mettre en œuvre leur propre)? Quelque chose comme *{'one','two','three'}
ça?
la source
find
avec l'--delete
option (pas besoin d'exécuterrm
pour chaque fichier. C'est une surcharge inutile).mv -t /tmp one two three && rm -rf * && mv -t . /tmp/one /tmp/two /tmp/three
, mais je préférerais une solution donnant la possibilité d'exclure explicitement quelque chose de*
. Il y aura sûrement des situations où le déplacement ou la copie des fichiers vers une autre destination ne sera pas une option.Réponses:
Pour Bash, il existe une option de shell appelée
extglob
qui est désactivée par défaut pour conserver la compatibilité avec la syntaxe standard du shell. Extglob complète la syntaxe des opérateurs supplémentaires comme!()
,?()
,@()
et un peu plus.Pour allumer
extglob
, tapezshopt -s extglob
. Pour le garder allumé pour le type d'utilisateur actuelecho 'shopt -s extglob' >> ~/.bashrc
.Pour l'exemple rm: Avec,
extglob
vous pouvez utiliserla source
shopt
chose dans votre~/.bashrc
, ça ne peut pas faire de mal.*
, mais ajoute à la place des indicateurs similaires (comme le!
) qui ont des fonctions supplémentaires? Dans ce cas, ce serait une belle solution.J'ai construit sauf exactement pour ça (désolé que je n'ai pas encore pu ajouter de documentation).
Si vous avez un dossier comme celui-ci:
La dactylographie
except b d
vous donneraa
etc
Maintenant, vous pouvez diriger cela vers
rm
.Cela peut être difficile à retenir, alors pourquoi ne pas simplement construire un script au-dessus de sauf, appelé
rm-except
:Tout aussi simple est
ls-except
:la source
Comme alternative à extglob (bien que ce soit une très bonne réponse et que tout le monde devrait avoir
shopt -s extglob globstar
dans son .bashrc), vous pouvez utiliser la variable globale $ GLOBIGNORE . Disons que vous voulez obtenir tous les fichiers sauf 'foo.txt' et 'bar baz.txt':... cependant, cela activera l'option shell
dotglob
, ce qui signifie que*
correspondra aux fichiers commençant par un point (qui sont normalement masqués). Vous avez donc réellement besoin de deux commandes:Comme il s'agit d'une variable globale, elle affectera chaque glob que vous utilisez jusqu'à ce que $ GLOBSTAR soit désactivé en vous déconnectant ou avec
Il ne fonctionnera également que sur les chaînes littérales passées à la variable. Vous pouvez voir ce que je veux dire en définissant $ GLOBIGNORE et en regardant la différence entre ces commandes:
la source