This should be pretty simple but I'm having an issue with the flow of an awk script. I run the following script and it prints the output over and over again (if I had to guess I would say that it's printing once for every line of the input file). As requested, here is some fake input:
[30000] (03/20 00:00:02.950):{0x2D90} Pattern1 5.0.3.57
[30000] (03/20 00:00:03.911):{0x2D90} Pattern2 5.0.3.57
[30000] (03/20 00:00:02.950):{0x2D90} Pattern3 5.0.3.16
[30000] (03/20 00:00:03.911):{0x2D90} Pattern4 5.0.3.16
Here is the script:
/Pattern1/ {
gsub(/\./,"");
agtver=$5;
}
/Pattern2/ {
gsub(/\./,"");
ctrver=$5;
}
{
if (agtver ~ 50357 && ctrver ~ 50357) {
print "Blamo!";
}
else print "No blamo. :("
}
And here is the output that I'm getting:
[chawkins@chawkins-DT Devel]$ ./fakeawk.awk < fake.txt
No blamo. :(
Blamo!
Blamo!
Blamo!
The output that I expect is a single Blamo!
if the patterns match and a single No blamo. :(
if it doens't match.
The problem seems to be that there are three separate { ... } sections, but I need these to be able to process two patterns... unless there is a way to condense this.
If you never see pattern1 and pattern2 after the first time, then agtver and ctrver remain set. You have to zero them out again.
edit added debug output, you should be able to see where the logic is failing. Tested with your data, thanks for adding that!
/Pattern1/ { gsub(/\./,""); agtver=$5;}
/Pattern2/ { gsub(/\./,""); ctrver=$5;}
{
#dbg print "\n#dbg: $5=" $5 "xx\tagtver=" agtver "xx\tctrver=" ctrver "xxx\t$0=" $0
if (agtver ~ 50357 && ctrver ~ 50357) {
print "Blamo!";
agtver="" ; ctrver=""
}
else print "No blamo. :("
}
./fakeawk.awk < fake.txt
output
No blamo. :(
Blamo!
No blamo. :(
No blamo. :(
I hope this helps.
agtver="" ; ctrver=""
. Good luck and will check back in 1/2 hr or so - shellter 2012-04-05 02:30
Blamo!
? Then do you just need to remove the else print "No blamo"
or if this is wrong, the please update your question with expected output. Good luck - shellter 2012-04-05 02:34
TXR:
@(gather :vars (agtver ctrver))
@ (skip :greedy) @/Pattern1/ @{agtver /5\.0\.3\.57/}
@ (skip :greedy) @/Pattern2/ @{ctrver /5\.0\.3\.57/}
@(end)
@(do (put-string "Blamo!\n"))
Output:
$ txr fake.txr fake.log
Blamo!
$ echo "junk" | txr fake.txr -
false
The @(gather)
directive is perfect for this. It matches material that can appear in any order, and :vars (agtver ctrver)
adds the constraint that bindings must be found for both of these variables, or else a failure occurs.
We can then express the two indepedent conditions we are looking for as a pair of independent whole-line pattern matches which bind two different variables.
The logic may be read as "please scan the input to gather bindings variables agtver
and ctrver
or else fail". And then the rules for gathering the variables are specified, one per line.
We don't really need the side effect of printing Blamo!
: the successful or failed termination of the program tells us everything.
Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo! Blamo!
The logic is working as expected, it's just outputting way too much - satori7 2012-04-04 22:35