Search code examples
regexbashmakefile

Using bash regex within a makefile


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?


Solution

  • \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]}