Quelle est la difference entre a[bc]d
et a{b,c}d
? Pourquoi les gens utilisent a{b,c}d
-ils quand il y en a déjà a[bc]d
?
brace-expansion
pattern-matching
Weijun Zhou
la source
la source
command a[bc]d
?ls
et que vous n'essayez que des caractères uniques, ils semblent fonctionner de la même manière.Réponses:
Les deux sont assez différents.
a[bc]d
est un modèle de nom de fichier (dans des shells autres quefish
). Il s'étendra aux deux noms de fichiersabd
etacd
s'il s'agit de noms de fichiers existants dans le répertoire en cours.La
[...]
partie est une expression entre crochets qui correspond à un seul caractère parmi ceux répertoriés (ou les éléments de classement lorsque des plages sont incluses). Pour faire correspondre le modèlea[bc]d
, le caractère entre les chaînesa
etd
dans un nom de fichier doit être ab
ou ac
.S'il
abd
existe, maisacd
n'existe pas, alors il ne ferait que s'étendre àabd
, et vice versa.Si ni
abd
, niacd
exister, en fonction de la coquille et les options, il déclencherait une erreur (Unix d' originesh
,(t)csh
,zsh
,fish
,bash -O failglob
) et peut - être sortir de la coquille, ou laisser le motif unexpanded¹ (Bourne-like etrc
-comme coquilles) ou étendre à rien (bash/zsh/yash -o nullglob
, certaines anciennes versions defish
, Unix d'originesh
et(t)csh
s'il y a d'autres globs correspondants dans la même commande).a{b,c}d
est une extension d'accolade (dans des coquilles qui les supportent). Il s'étendra aux deux chaînesabd
etacd
.La
{...}
pièce est un ensemble délimité par des virgules des chaînes (dans cet exemple, dans certains obus, il peut également être une plage telle quea..k
ou20..25
ceux ou plus avancés comme00..20..2
ou0..20..2%02d
), et l'expansion est calculée en combinant chacun de ces chaînes avec le flanquante cordesa
etd
. Ces chaînes peuvent être plus longues qu'un seul caractère et peuvent également être des extensions d'accolade elles-mêmes.L'expansion se produit indépendamment du fait que ces chaînes correspondent ou non aux noms de fichiers existants.
Si vous construisez des chaînes, utilisez une extension d'accolade. Si vous faites correspondre des noms de fichiers, utilisez un modèle de nom de fichier.
¹ Dans ce cas particulier, il
a[bc]d
peut arriver que ce soit le nom d'un fichier existant, c'est pourquoi il est potentiellement dangereux d'utiliser des choses commerm -f ./*.[ch]
celles-ci etrm -f ./*.{c,h}
c'est moins un problème.la source
a{b,c}d
, les partiesb
etc
n'ont pas besoin d'être des lettres simples; par exempleex{ten,ci}sion
. Alors queex[tenci]sion
ou quoi que ce soit ne correspondra qu'à l' une de ces lettres.a[bc]d
correspond au modèle et fait partie de la norme POSIX. Dans POSIX, ceci est introduit comme "expression de parenthèse de modèle". Il est documenté dans la section 2.13 du manuelLa section 2.13.3 mentionne également quelque chose qui se comporte différemment de ce à quoi on pourrait s'attendre pour les expressions rationnelles habituelles quand il est utilisé pour l'expansion du nom de fichier (c'est moi qui souligne)
a{b,c}d
est l' expansion des accolades , ce n'est pas dans la spécification de POSIX. Voici la partie correspondante du manuel bash (souligné par moi):Selon le commentaire de @mosvy, cela est apparu pour la première fois,
csh
mais le comportement dansbash
est différent decsh
et d'autres coquilles. Ce type d'expansion de croisillons est également présent dansglob(3)
.Il existe un autre type d'expansion d'accolades
{a..z}
qui n'apparaît qu'aprèsbash
3.0, et il y en a d'autres ajoutées dansbash
4.0.Dans un shell où la globalisation est activée, exécutez dans un dossier vide, le résultat suivant est retourné
En réponse au commentaire de @ Jesse_b, si vous êtes dans un shell interactif et que les deux s'appliquent, il
a[bc]d
est moins difficile de taper. Par exemplegrep pattern [ab][12].txt
.la source
csh
bien avantbash
. Il est également présent dans la fonction de bibliothèque glob (3). La différence est que dansbash
elle est effectuée avant les autres extensions:a=A; ab=A/B; ac=A/C; echo $a{b,c}
fonctionnera dans bash différemment de tout autre shell.