I would like to tell if a string $string
would be matched by a glob pattern $pattern
. $string
may or may not be the name of an existing file. How can I do this?
Assume the following formats for my input strings:
string="/foo/bar"
pattern1="/foo/*"
pattern2="/foo/{bar,baz}"
I would like to find a bash idiom that determines if $string
would be matched by $pattern1
, $pattern2
, or any other arbitrary glob pattern. Here is what I have tried so far:
[[ "$string" = $pattern ]]
This almost works, except that
$pattern
is interpreted as a string pattern and not as a glob pattern.[ "$string" = $pattern ]
The problem with this approach is that
$pattern
is expanded and then string comparison is performed between$string
and the expansion of$pattern
.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]
This one works, but only if
$string
contains a file that exists.[[ $string =~ $pattern ]]
This does not work because the
=~
operator causes$pattern
to be interpreted as an extended regular expression, not a glob or wildcard pattern.
{bar,baz}
isn't a pattern. It's parameter expansion. Subtle but critical difference in that{bar,baz}
is expanded very early on into multiple arguments,bar
andbaz
. – phemmer Nov 04 '14 at 20:25ls /foo/*
now you can match in a – Hackaholic Nov 04 '14 at 20:32foo/{bar,baz}
is actually a brace expansion (not a parameter expansion) whilefoo/*
is pathname expansion.$string
is parameter expansion. These are all done at different times and by different mechanisms. – jayhendren Nov 04 '14 at 20:45case
statement performs Pathname Expansion ("globbing") as per the Bash manual. – Mike S Aug 16 '16 at 20:17compgen -G "<glob-pattern>"
for bash. – Wtower Mar 12 '17 at 09:21