Pourquoi ne puis-je pas utiliser! (Motif unique) dans zsh même après avoir activé kshglob?

8

Cela fonctionne en bash:

touch a b c
echo !(a)

Si j'exécute le script ci-dessus dans zsh (avec kshglobon), il se plaint:

zsh: number expected

Si j'ajoute |après a, ça marche:

echo !(a|)

Pourquoi?

dedowsdi
la source

Réponses:

10

Parce que dans ce cas, il entre en conflit avec les qualificateurs de glob nus car il est à la fin du modèle. *(a1)est pris comme dernier accès aux fichiers le dernier jour. (a1)est traité comme un qualificatif glob. Donc dans votre !(a)cas, zsh se plaint du nombre de jours manquant après le aqualificatif glob (appliqué ici au fichier appelé !).

Dans les zshglobs, le (...)regroupement est principalement utilisé pour l' (foo|bar)alternance, l'ajout de a |est donc un moyen documenté de s'assurer qu'un suivi (...)n'est pas traité comme un qualificatif de glob.

Une autre alternative documentée consiste à doubler la parenthèse ( !((a))) ou vous pouvez ajouter un qualificateur de glob vide (comme !(a)(-)).

Pour supprimer complètement cette ambiguïté, on peut désactiver l' bare_glob_qualoption ( set +o bareglobqual), après quoi les qualificatifs glob doivent être écrits avec la extendedglob (#q...)syntaxe ( *(#qa1)ici).

L' kshgloboption ( ajoutée en 1998 , à peu près en même temps a bashajouté que son extglobbash n'avait pas de glob étendu avant) est principalement disponible pour le kshmode d'émulation ( emulate ksh), pour zshpouvoir exécuter des kshscripts, où kshglobest activé et bareglobqualdésactivé. Quand il a été introduit pour la première fois, après l'activation kshglob, vous devez spécifier des qualificatifs glob -(...)pour éviter ce type de conflit, mais cela a causé trop de confusion et est entré en conflit avec la @-(...)syntaxe de ksh93, les options (#q...)et bareglobqualont été introduites plus tard.

zshles utilisateurs préfèrent généralement les propres set -o extendedglobopérateurs glob ( ) étendus de zsh qui sont plus faciles à taper (pour la plupart) et plus puissants (que ceux ksh88 activés avec kshglobégalement trouvés dans bash -O extglob).

Par exemple, !(foo)serait écrit ^foo. L' !(foo|)baréquivalent serait cependant plus long (^(foo|))bar.

Autres traductions de ksh88 -> zsh:

  • *(x) -> x#
  • +(x) -> x##
  • @(x|y) -> x|y
  • ?(x) -> (x|)

Quelques traductions de ksh93 -> zsh:

  • ~(i:x)-> (#i)x(insensible à la casse)
  • ~(N)x-> x(N)(nullglob, originaire de zsh)
  • {1,5}(x) -> x(#c1,5)
  • @(foo&bar)-> foo~^barou^(^foo|^bar)

Certains ne se trouvent que dans zsh:

  • <1-23> (plage de nombres décimaux)
  • pattern~except
  • pattern(glob-qualifier) (la fonction de tueur des globes zsh)
  • (pattern/)#(n'importe quel niveau de sous-répertoires correspondant à pattern; la **/version simplifiée de (*/)#a également été ajoutée à ksh93 et ​​bash récemment)
  • ***/* (globbing récursif suivant les liens symboliques).
  • (#a1)foobar (correspondance approximative, permettant quelques erreurs, ici 1)
  • ...
Stéphane Chazelas
la source