J'ai cette situation où je veux exclure un répertoire en utilisant la commande mv
. J'ai vu cet exemple où la syntaxe serait !(exclude_dir)
, mais lorsque je configure un scénario pour le tester, j'obtiens des résultats que je ne comprends pas bien.
Maintenant, j'ai créé trois dossiers: f1
, f2
et f3
. Maintenant, j'utilise la commande de cette façon:
mv -t f3/ !(f1) f2
Cela produit cette erreur:
mv: cannot move 'f3' to a subdirectory of itself, 'f3/f3'
mv: cannot stat 'f2': No such file or directory
Ce qui est drôle, c’est que la structure du dossier est maintenant:
.
├── f1
└── f3
└── f2
3 directories, 0 files
Il fait ce que je veux mais pourquoi les messages d'erreur. Évidemment je n'utilise pas cette commande correctement.
Cela n'a rien à voir avec mv
, mais est une fonction bash
citant man bash
:
Si l'option de shell extglob est activée à l'aide de la commande intégrée shopt , plusieurs les opérateurs de correspondance de modèle sont reconnus. Dans la description suivante, une liste de modèles est une liste d'un ou plusieurs modèles séparés par un |. Les motifs composites peuvent être formés en utilisant un ou plusieurs des sous-motifs suivants:
! (liste de motifs)
Correspond à tout sauf à l'un des motifs donnés
!(f1)
correspond à _f2 f3
_ dans votre exemple, donc vous faites effectivement:
_mv -t f3/ f2 f3 f2
_
Pour atteindre votre objectif, vous devriez plutôt faire:
_mv -t f3/ !(f[13]) # or !(f1|f3)
_
Cette expression correspond à tout sauf à _f1
_ et à _f3
_.
Cela fonctionne également avec _*
_, _?
_ et _[…]
_:
_$ ls
e1 e2 e3 f1 f2 f3
$ ls !(e*|?[12])
f3
_
!(f1)
est une expression globale étendue . Par conséquent (à condition que l'option extglob
Shell soit définie), elle se développe en liste de fichiers (non) correspondants. En d’autres termes, si votre répertoire contenait initialement f1
, f2
, f3
alors
mv -t f3/ !(f1) f2
se développe en tant que
mv -t f3/ f2 f3 f2
La première erreur devrait être évidente; le second est parce qu'il tente de déplacer f2
deux fois - et échoue une deuxième fois.