2016-05-28 2 views
1

Le manuel bash (j'utilise la version 4.3.42 sur OSX) indique que la barre verticale '|' Le caractère est utilisé comme séparateur pour plusieurs modèles de fichier dans l'agrégation de fichiers. Ainsi, ce qui suit devrait fonctionner sur mon système:anomalie de globbing de fichier bash

projectFiles=./config/**/*|./support/**/* 

Cependant, le second motif donne une « Autorisation refusée » sur le dernier fichier qui se trouve dans cette structure de répertoire de sorte que le motif est jamais résolu en ProjectFiles. J'ai essayé des variations sur ce sujet, y compris envelopper les motifs entre parenthèses,

projectFiles=(./config/**/*)|(./support/**/*) 

qui est disposé dans le manuel, mais cela ne fonctionne pas non plus.

Des suggestions sur ce que je fais mal?

+3

Pouvez-vous lier la partie pertinente de ce manuel? Dans le script shell, '|' est utilisé pour le piping entre les programmes. Votre erreur "permission denied" est d'essayer d'exécuter quoi que ce soit './support/**/*' résout. –

+1

En outre, la globalisation n'est pas effectuée * du tout * lors d'une affectation simple; essayez 'foo = *', puis comparez 'echo" $ foo "' avec 'echo $ foo'. La globalisation se produit pendant l'assignation * array *; voir 'foo = (*)'; echo "$ {foo [@]}" '. – chepner

+1

Notez que vous pouvez le faire sans extglob, './ {config, support}/**/*', qui se développerait juste avec le chemin avec config et le chemin avec l'espace de support délimité, puis faire une correspondance de modèle. Ou './@ (config | support)/**/*' avec extglob. L'un ou l'autre semble plus propre. – BroSlow

Répondre

6

Vous faites sans doute allusion à cette partie dans man bash:

If the extglob shell option is enabled using the shopt builtin, several 
    extended pattern matching operators are recognized. In the following 
    description, a pattern-list is a list of one or more patterns separated 
    by a |. Composite patterns may be formed using one or more of the fol- 
    lowing sub-patterns: 

      ?(pattern-list) 
       Matches zero or one occurrence of the given patterns 
      *(pattern-list) 
       Matches zero or more occurrences of the given patterns 
      +(pattern-list) 
       Matches one or more occurrences of the given patterns 
      @(pattern-list) 
       Matches one of the given patterns 
      !(pattern-list) 
       Matches anything except one of the given patterns 

Le séparateur | fonctionne dans les listes de modélistes comme expliqué, mais seulement quand extglob est activé:

shopt -s extglob 

Essayez ceci:

projectFiles=*(./config/**/*|./support/**/*) 

Comme @BroSlow a souligné dans un commentaire:

Notez que vous pouvez le faire sans extglob, ./{config,support}/**/*, qui vient élargir le chemin avec config et le chemin avec un espace de support délimité, puis faire des filtrages . Ou ./@(config|support)/**/* avec extglob. L'un ou l'autre semble plus propre.

commentaire de @chepner est également intéressant de mentionner:

En outre, globbing n'est pas effectuée du tout au cours d'une simple affectation; essayez foo=*, puis comparez echo "$foo" avec echo $foo. Globbing se produit pendant l'assignation de tableau; voir foo=(*); echo "${foo[@]}"

+0

Merci, @janos ... deux choses: 1) projectFiles = * (./ config/**/* |./ support/**/*) ne fonctionnait pas; tout ce que je reçois est "No tel fichier ou répertoire" lors de l'exécution 'ls $ projectFiles' 2) echo $ foo fait le fichier globbing tout en echo" $ foo "renvoie '*' - bel exemple pour signaler la différence – JESii

+0

Et oui. .. c'était la section dans l'homme bash qui a attiré mon attention – JESii

+0

Et ... vos deux autres options - ./{config,support}/**/* et ./@(config|support)/**/* - les deux travaillent. Merci à vous et à BroSlow et à votre chepner pour la réponse combinée! – JESii