Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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]/)
This however does not work, and I've not found a way to combine a variable and regular expression in the search pattern. Any help greatly appreciated.

share|improve this question
up vote 5 down vote accepted
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}/)
share|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 at 15:11

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
share|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 at 15:14
    
@Carlos so you want the pattern matching to be case insensitive ? – Serg Jan 27 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 at 20:24

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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