Combine variable and regular expression in pattern match

SP="ABC" 
if ( $1 ~ "^" SP "[0-9]{3}")

You can concatenate strings but not /xxx/s which are in effect more like regular expression matching operators, and with parsing rules that can get confusing (and vary between implementations)

$1 ~ /ABC/ /BCD/

could be seen as the concatenation of $1 matched against the concatenation of /ABC/ (1 or 0 depending on whether $0 matches /ABC/) and /BCD/ (1 or 0 depending on whether $0 matches /BCD/), or $1 matched against /ABC/ (0 or 1) concatenated with $0 matched against /BCD/ which would be confusing enough except that the /regexp/ operator doesn't work well when combined with some others like the concatenation operator here, as there's a possible confusion with the / division operator.

But with parenthesis, you can get interesting (read buggy) behaviours:

$ echo 11 ab | gawk '{print $1 ~ /a/ (/b/)}'
1
$ echo 11 ab | bwk-awk '{print $1 ~ /a/ (/b/)}'
01
$ echo b | bwk-awk '{print /a/ - (/b/)}'
0-1

(that latter one being the result of /a/ (0) concatenated with the result of - (/b/)).


note that in $1 =~ "^" SP "[0-9]{3}", SP's content is still treated as a regexp (if it's ..., that matches 3 characters, not 3 dots); if that's not wanted:

if (index($1, SP) == 1 && substr($1, length(SP)+1) ~ /^[0-9]{3}/)

You can tell awk to read regular expression starting with exact chars, and then with a charater "type" in square brackets, followed by repetition number in curly brackets. Like so:

echo "ABC956" |  awk '{ if( $1 ~ /^ABC[0-9]{3}/) print "HELLOWORLD" }'                                 
HELLOWORLD

You could use logical operator && to test for presence of both variable and the regular expression as well

echo "ABC956" |  awk -v VAR="ABC" '{ if( $1 ~ VAR && $1 ~ /[0-9]{3}/) print "HELLOWORLD" }'            
HELLOWORLD

Tags:

Awk