Redson
Redson

Reputation: 2140

How to match part of a string to a regex in bash?

I am using a regular expression to match many file names with similar names. See the files below.

file1="CGInoimport"
file2="doCGIimport"
file3="donoCGInoimport"
file4="importCGIno"

I am using a for loop to iterate through each file variable to check if the regular expression matches. I am trying to isolate file name containing the word CGI. Here is what I have so far.

for (( i=1; i < 5; i++ )) ; do
    if [[ file$i =~ ^CGI$ ]] ; then
        echo "There is a CGI in the name"
    else
        echo "This shouldn't happen"
    fi
done

The problem is for each file, I am getting This shouldn't happen. I know there is a problem with the regular expression but I don't know how to fix it. Any suggestions?

Let me know if further explanation is required.

Upvotes: 1

Views: 719

Answers (1)

Charles Duffy
Charles Duffy

Reputation: 295766

The regex ^CGI$ only matches when the entire string is CGI. If you want to match any substring, use simply CGI.

This is because in a regular expression, ^ only matches at the beginning of a string ("anchors" to the beginning), and $ only at the end. That said, it's more conventional to use shell-style patterns here (with the = operator rather than =~), and simply use wildcards to disable their implicit anchoring.

Finally, since you want to look up through a variable lookup, you need to use variable indirection. So:

varname=file$i
if [[ ${!varname} = *CGI* ]]; then
  echo "There is a CGI in the name"
fi

That said, the better way to do it would be to use an array. So:

files=( CGInoimport doCGIimport donoCGInoimport importCGIno )
for file in "${files[@]}"; do
  [[ $file = *CGI* ]] && echo "There is CGI in the name $file"
done

...or, if the keys can be non-numeric or discontiguous, an associative array:

declare -A files=(
  [file1]=CGInoimport
  [file2]=doCGIimport
  [file3]=donocCGInoimport
  [file4]=importCGIno
)
for key in "${!files[@]}"; do
  [[ ${files[file$key]} = *CGI* ]] && echo "There is CGI in $key"
done

Upvotes: 5

Related Questions