Bash – How to programmatically tell if a filename matches a shell glob pattern

bashwildcards

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:

  1. [[ "$string" = $pattern ]]

    This almost works, except that $pattern is interpreted as a string pattern and not as a glob pattern.

  2. [ "$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.

  3. [[ "$(find $pattern -print0 -maxdepth 0 2>/dev/null)" =~ "$string" ]]

    This one works, but only if $string contains a file that exists.

  4. [[ $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.

Best Answer

I don't believe that {bar,baz} is a shell glob pattern (though certainly /foo/ba[rz] is) but if you want to know if $string matches $pattern you can do:

case "$string" in 
($pattern) put your successful execution statement here;;
(*)        this is where your failure case should be   ;;
esac

You can do as many as you like:

case "$string" in
($pattern1) do something;;
($pattern2) do differently;;
(*)         still no match;;
esac