I have a makefile (which uses the SHELL := /bin/bash
target) that I would like to parse a string var in to retrieve a substring, I'm trying to make sense of the escaping rules for the bash regex language but it's not clicking for me. If I store the regex in a variable, I can use it in a bash line as follows:
$ RE="(\w+\/)*(\w{3}-[0-9]+).*"
$ [[ "foo/foo-123" =~ $RE ]] && echo ${BASH_REMATCH[2]}
foo-123
$
however if I try to use the regex in the command itself it will not work:
$ [[ "foo/foo-123" =~ (\w+\/)*(\w{3}-[0-9]+).* ]] && echo ${BASH_REMATCH[2]}
$
and even if I enclose it in quotes, or use:
$ [[ "foo/foo-123" =~ ^(\w+\/)*(\w{3}-[0-9]+).*$ ]] && echo ${BASH_REMATCH[2]}
$
it no longer matches. If I try to use the first solution in my makefile it also does not correctly parse the substring. I understand there are further escaping problems due to using $
in the makefile but I'm confused as to why I experience them in bash, is there a better way to achieve what I want to do in the makefile or if not, what am I missing to get this approach working?
\w
is not supported in bash. Also, +{3}
doesn't make much sense, use just {3}
. Moreover, the final .*
is not needed - the regex doesn't have to match the whole string.
[[ foo/foo-123 =~ ([[:alpha:]]+/)*([[:alpha:]]{3}-[0-9]+) ]] && echo ${BASH_REMATCH[2]}
In a Makefile, you need to double the dollar signs:
SHELL = /bin/bash
test:
[[ foo/foo-123 =~ ([[:alpha:]]+/)*([[:alpha:]]{3}-[0-9]+) ]] && echo $${BASH_REMATCH[2]}