web-dev-qa-db-fra.com

Comment exclure un dossier en utilisant la commande mv

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.

3
George Udosen

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
_
8
dessert

!(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.

4
steeldriver