bashshell

How to check if a file name matches regex in shell script


I have a shell script that needs to check if a file name matches a certain regex, but it always shows "not match". Can anyone let me know what's wrong with my code?

fileNamePattern=abcd_????_def_*.txt
realFilePath=/data/file/abcd_12bd_def_ghijk.txt

if [[ $realFilePath =~ $fileNamePattern ]]
then
    echo $realFilePath match  $fileNamePattern
else
    echo $realFilePath not match $fileNamePattern
fi

Solution

  • There is a confusion between regexes and the simpler "glob"/"wildcard"/"normal" patterns – whatever you want to call them. You're using the latter, but call it a regex.

    If you want to use a pattern, you should

    If you want to use a regex, you should:

    The BashGuide has a great article about the different types of patterns in Bash.

    Notice that quoting your parameters is almost always a good habit. It's not required in conditional expressions in [[ ]], and actually suppresses interpretation of the right-hand side as a pattern or regex. If you were using [ ] (which doesn't support regexes and patterns anyway), quoting would be required to avoid unexpected side effects of special characters and empty strings.


    1 Not exactly true in this case, actually. When assigning to a variable, the manual says that the following happens:

    [...] tilde expansion, parameter and variable expansion, command substitution, arithmetic expansion, and quote removal [...]

    i.e., no pathname (glob) expansion. While in this very case using

    fileNamePattern=abcd_????_def_*.txt
    

    would work just as well as the quoted version, using quotes prevents surprises in many other cases and is required as soon as you have a blank in the pattern.