8

I have a nice little bash script which parses a message for a regular expression and does something with the capture groups:

regex='\((Closes|Resolves):\s([0-9]+)\)'
msg='Fixed a problem (Closes: 1234), (Resolves: 5678)'

if [[ $msg =~ $regex ]] ; then
  action="${BASH_REMATCH[1]}"
  issue="${BASH_REMATCH[2]}"
  do_something $action $issue
fi

This works well for the first match, but if there are multiple matches msg, later matches are ignored. Is there a way for me to loop through each match or is it time to start thinking of python or perl?

8

It's not explicitly supported by built-in bash syntax, but it can be easily achieved with a little variable substitution and some recursion.

function do_something {
  echo $1 $2
}

function handlematches {
  regex='\((Closes|Resolves):\s([0-9]+)\)'
  msg=$1

  if [[ $msg =~ $regex ]] ; then
    action="${BASH_REMATCH[1]}"
    issue="${BASH_REMATCH[2]}"
    do_something "$action" "$issue"

    # Remove the first regex match and try again
    handlematches "${msg/${BASH_REMATCH[0]}/}"
  fi
}

message='Fixed a problem (Closes: 1234), (Resolves: 5678)'
handlematches "$message"

Output:

Closes 1234
Resolves 5678
2

Similar to Stewart's answer, but using an iterative rather than recursive approach:

regex='\((Closes|Resolves): ([0-9]+)\)'
msg='Fixed a problem (Closes: 1234), (Resolves: 5678)'

while [[ $msg =~ $regex ]]; do
        action=${BASH_REMATCH[1]}
        issue=${BASH_REMATCH[2]}
        do_something "$action" "$issue"

        msg=${msg/"${BASH_REMATCH[0]}"/}
done

This iterates over the string in $msg until the regular expression no longer matches. In each iteration, the matching bit is remove using a bash parameter substitution.

If you want to hold on to the original $msg, then make a copy of it in another variable first.

With

do_something () {
        printf 'action=%s, issue=%s\n' "$1" "$2"
}

this outputs

action=Closes, issue=1234
action=Resolves, issue=5678

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.