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
$patternis interpreted as a string pattern and not as a glob pattern.[ "$string" = $pattern ]The problem with this approach is that
$patternis expanded and then string comparison is performed between$stringand the expansion of$pattern.[[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]This one works, but only if
$stringcontains a file that exists.[[ $string =~ $pattern ]]This does not work because the
=~operator causes$patternto 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,barandbaz. – 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.$stringis parameter expansion. These are all done at different times and by different mechanisms. – jayhendren Nov 04 '14 at 20:45casestatement 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