-2

I am trying to use regex to match a filename out of a path.

#!/bin/bash
regex=[^/]+?(?=.zip)
path="/home/quid/Downloads/file.zip"

if [[ $path =~ $regex ]]
then
     echo "Found a match"
     echo $BASH_REMATCH
fi

I should get

Found a match
file

Instead bash gives me this error

another.sh: line 2: syntax error near unexpected token `('
another.sh: line 2: `reg=[^/]+?(?=.zip)'

If I put the regex in a quotes, it no longer is recognized as regex. I have zsh 5.8 and bash 5.0.16 and it doesn't work on both shells.

How can I get bash to recognize the regex or not give me an error for using regex groups?

3leggedquid
  • 67
  • 1
  • 4
  • `(?=...)` is not valid POSIX ERE syntax. Be sure you use the right regex language variant. – Charles Duffy Apr 18 '20 at 01:16
  • ERE doesn't allow non-greedy modifiers either. `+?` and `*?` don't mean anything here. – Charles Duffy Apr 18 '20 at 01:17
  • `regex='([^/.]+)([.]zip)?$'` may not be exactly what you want, but its validity does demonstrate that grouping is not the part of your original expression that's illegal. – Charles Duffy Apr 18 '20 at 01:20
  • BTW, you need to use quotes when assigning to the `regex` variable, and **not** use quotes when expanding that variable, to get consistent and reliable behavior. – Charles Duffy Apr 18 '20 at 01:23
  • Thank you for the help Charles. I have been testing on regexr which used the javascript ERE so that explains why it doesn't work with bash. Thanks for the extra tips. I'll be trying to just get "file" and not "file.zip" now. – 3leggedquid Apr 18 '20 at 01:25
  • `if grep -P "$regex" <<< "$path"` maybe, assuming you have the quotes on the regex assignment as what @CharlesDuffy said. requires `grep` that has `-P` – Jetchisel Apr 18 '20 at 01:27
  • BTW, JavaScript regexes are closer to PCRE than ERE. "javascript ERE" isn't really a thing. – Charles Duffy Apr 18 '20 at 04:04

1 Answers1

-1
#!/bin/bash
regex='([^/.]+)([.]zip)?$'
path="/home/quid/Downloads/file.zip"

if [[ $path =~ $regex ]]
then
     echo "Found a match"
     echo "${BASH_REMATCH[1]}"
fi

Using Charles' regex and ${BASH_REMATCH[1]} gives me just the file name without the extension.

3leggedquid
  • 67
  • 1
  • 4
  • 1
    `echo "${BASH_REMATCH[1]}"` -- see [BashPitfalls #14](http://mywiki.wooledge.org/BashPitfalls#echo_.24foo). – Charles Duffy Apr 18 '20 at 02:14
  • 2
    That said, usually I wouldn't use a regex for this at all. `filename=${path##*/}; filename=${filename%.zip}` will arrive at your original intent, using only parameter expansions. – Charles Duffy Apr 18 '20 at 02:14