Extract regex capture groups using [[ and BASH_REMATCH

text='3 blue; 5 green'; [[ $text =~ ([0-9]+)" "(blue|green) ]] && { echo "count = ${BASH_REMATCH[1]}"; echo "color = ${BASH_REMATCH[2]}"; }

December 4, 2023bashoneliners

Explanation

The example one-liner will print:

count = 3
color = blue
  • text='3 blue; 5 green' assigns some example text in the variable text
  • [[ $text =~ ([0-9]+)" "(blue|green) ]] tests if the value of $text matches the extended regex ([0-9]+)" "(blue|green), that is:
    • [0-9]+ -- 1 or more digits
    • " " -- followed by a space; note: it was important to enclose this space in quotes
    • blue|green -- the color "blue" or "green"
    • The parts of the regex enclosed in parentheses (...) will be available in the BASH_REMATCH array, if the pattern match is successful.
  • The group of commands chained after [[ ... ]] with && { ...; } will be executed only if the [[ ... ]] command was successful.
  • The echo commands print the captured expression in the first and second parenthesized subexpressions (...), in this example a count and a color.

Additional tips:

  • The entire matched expression is stored in ${BASH_REMATCH[0]}, in this example the value would be "3 blue".
  • If the nocasematch shell option is enabled, the match is performed case insensitively. For example if the example text was "3 Blue", that normally would not match, unless you run shopt -s nocasematch first before performing the matching. (Clear the shell option with shopt -u nocasematch if needed.)