6

I am looking to search a file for a column that is 3 letters followed by any 3 or 4 numerals. eg.

if ( $1 ~ /^[A-Z][A-Z][A-Z][0-9][0-9][0-9]/) 

However I need the 3 letters to be a variable, so I am looking for the result of

SP="ABC" 
if ( $1 ~ /^/SP/[0-9][0-9][0-9]/)>

However, this does not work. How do I combine a variable and regular expression in the search pattern?

7
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}/)
| improve this answer | |
  • Exactly what I needed. Looks like I had the right idea, just needed quotes instead of slashes. Thank you muchly. – Carlos Jan 27 '16 at 15:11
2

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
| improve this answer | |
  • Thank you. I had tried this option, but ran into a problem where the data was abcde123, which this captures, but I don't want. – Carlos Jan 27 '16 at 15:14
  • @Carlos so you want the pattern matching to be case insensitive ? – Sergiy Kolodyazhnyy Jan 27 '16 at 16:17
  • no, all text in this particular file is upper case. My example of abcde123 was just relative to the extra "de" between abc and 123. – Carlos Jan 28 '16 at 20:24

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.