The bash manual (I'm using version 4.3.42 on OSX) states that the vertical bar '|' character is used as a separator for multiple file patterns in file globbing. Thus, the following should work on my system:
projectFiles=./config/**/*|./support/**/*
However, the second pattern gives a "Permission denied" on the last file that is in that directory structure so the pattern is never resolved into projectFiles. I've tried variations on this, including wrapping the patterns in parentheses,
projectFiles=(./config/**/*)|(./support/**/*)
which is laid out in the manual, but that doesn't work either.
Any suggestions on what I'm doing wrong?
You're probably referring to this part in 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
The |
separator works in pattern-lists as explained, but only when extglob
is enabled:
shopt -s extglob
Try this:
projectFiles=*(./config/**/*|./support/**/*)
As @BroSlow pointed out in a comment:
Note that you can do this without
extglob
,./{config,support}/**/*
, which would just expand to the path with config and the path with support space delimited and then do pattern matching. Or./@(config|support)/**/*
withextglob
. Either of which seems cleaner.
@chepner's comment is also worth mentioning:
Also, globbing isn't performed at all during a simple assignment; try
foo=*
, then compareecho "$foo"
withecho $foo
. Globbing does occur during array assignment; seefoo=(*); echo "${foo[@]}"