One liner matching filenames with regular expressions?

10,482

Using only the string match, you need to use =~ (which matches against an extended regular expression):

if [[ "${FILENAME}" =~ "FOO[0-9][0-9]_(bar|dog|cat)" ]]

or

NAME="FOO[0-9][0-9]_(bar|dog|cat)"
if [[ "${FILENAME}" =~ ${NAME} ]]

to match your original.

== is always a globbing match (or an exact match if globs are disabled), it can’t be used with regular expressions.

Alternatively, if you can make more changes to the script, assuming you’re using GNU find, you can filter with find:

find ${DIR} -maxdepth 1 -type f -regextype posix-extended -regex ".*/FOO[0-9][0-9]_(bar|dog|cat)\.[Dd][Oo][Cc]"

(-regextype posix-extended tells find we want to use extended regular expressions, and the regular expression itself starts with .*/ because -regex matches the whole path, not just the filename.)

Share:
10,482

Related videos on Youtube

SHLelieveld
Author by

SHLelieveld

Linux Specialist in the making. Learning as much as I possibly can.

Updated on September 18, 2022

Comments

  • SHLelieveld
    SHLelieveld almost 2 years

    I have a small script.

    #!/bin/bash
    # test for regular expressions to match...
    DIR="/search/path/"
    NAME="FOO[0-9][0-9]_<bar|dog|cat>"
    
    for FILE in `find ${DIR} -maxdepth 1 -type f -name "*\.[dD][oO][cC]"` 
    do
        BASENAME=`basename ${FILE}`
        FILENAME="${BASENAME%.*}"
    
        if [[ "${FILENAME}" == ${NAME} ]]
        then
                echo "Found $FILENAME"
        else
                echo "$FILENAME not matching..!"
        fi
    
    done
    

    In this script I want to match all files that start with FOO[0-9[0-9]_ and then either bar, dog, or cat. But if something else is there like bog or cog or car it should NOT match.

    When I do [a-z][a-z][a-z] they will match...

    I already tried doing something like:

    NAME="FOO[0-9][0-9]_(bar|dog|cat)"
    or
    NAME="FOO[0-9][0-9]_bar|dog|cat"
    or
    NAME="FOO[0-9][0-9]_[bar|dog|cat]"
    or
    NAME="FOO[0-9][0-9]_'bar|dog|cat'"
    

    But in the documentation about regular expressions I could not find an exact match.

    I need to have it in a single line, as the main script I use it for is a lot more complex and have a lot of different sub processes hanging off of it.

    Is this even possible...?

  • SHLelieveld
    SHLelieveld almost 6 years
    Thanks for the quick reply. The issue is this: the find + if loop is in a function, and the DIR and NAME variable is are set over and over again and in each folder the names that are accepted are different. so the variable NAME needs to have the 'bar' or 'dog' or 'cat' regexp. I'll give this a try: NAME="FOO[0-9][0-9]_(bar|dog|cat)" if [[ "${FILENAME}" =~ "${NAME}" ]]
  • Stephen Kitt
    Stephen Kitt almost 6 years
    See the (originally) second part of my answer, which works with those constraints (apart from ==).
  • Stephen Kitt
    Stephen Kitt almost 6 years
    Oh wait the quotes are wrong, try the updated version.