I believe what you are after is something which resembles BASH_REMATCH
.
An additional binary operator, =~
, is available, with the
same precedence as ==
and !=
. When it is used, the string
to the right of the operator is considered an extended
regular expression and matched accordingly (as in regex(3)).
The return value is 0 if the string matches the pattern, and 1
otherwise. If the regular expression is syntactical
incorrect, the conditional expression's return value is 2. If
the shell option nocasematch
is enabled, the match is performed
without regard to the case of alphabetic characters. Any part
of the pattern may be quoted to force it to be matched as a
string. Substrings matched by parenthesized subexpressions
within the regular expression are saved in the array variable
BASH_REMATCH
. The element of BASH_REMATCH
with index 0 is
the portion of the string matching the entire regular
expression. The element of BASH_REMATCH
with index n
is
the portion of the string matching the nth parenthesized
subexpression.
Unfortunately, glob patterns and regular expressions are not
the same (See this question, and this linuxjournal article). Nonetheless, we can make a one-to-one translation:
|-------+-------+---------------------------------------|
| glob | regex | remark |
|-------+-------+---------------------------------------|
| * | [^/]* | filenames don't have a / |
| **/ | .*/ | ** repreensts full paths (end with /) |
| ? | [^/] | filenames don't have a / |
| [...] | [...] | the character groups are the same |
|-------+-------+---------------------------------------|
You have to be careful though, as some characters have special meanings in regular expressions, but not in globular expressions. (Eg. .
, +
):
So in the example of the OP, you can do this:
for file in foo-*.csv; do
[[ "${file}" =~ foo-([^/]*)[.]csv ]]
echo "${BASH_REMATCH[1]}"
done
Or a more complicated example:
for file in *-substring-[0-3a-9]-foo?.file
[[ "${file}" =~ ([^/]*)-substring-([0-3a-9])-foo(.)[.]file ]]
echo "${BASH_REMATCH[1]} ${BASH_REMATCH[2]} ${BASH_REMATCH[3]}"
done