Trying to learn to use functions in gawk and not getting expected output.

I've been working on improving my awk, and the next thing I want to learn is to properly use functions (I understand functions in shell and python). I have the following code which includes how I did this without functions before, and two attempts I've made to do it with functions:

function div(n, d)
{
  if (n == 0) {
  	return n
  } else {
  	return substr(n / d * 100, 0, 5)
  }
}

BEGIN{ 
    OFS=",";SUBSEP=","
     }
      $7   == 17018      {SETUP[$1,substr($2,0,2)]++ ; DT[$1,substr($2,0,2)]++ }
      $7   == 17030      { SUCC[$1,substr($2,0,2)]++ ; DT[$1,substr($2,0,2)]++ }
      $7   == 17120      {  FWD[$1,substr($2,0,2)]++ ; DT[$1,substr($2,0,2)]++ ; SETUP[$1,substr($2,0,2)]-- }
      $7   == 17014      { TIME[$1,substr($2,0,2)]++ ; DT[$1,substr($2,0,2)]++ ;  SUCC[$1,substr($2,0,2)]-- }
      $19  == "(Missing" { MISS[$1,substr($2,0,2)]++ ; DT[$1,substr($2,0,2)]++ }
END{
    for (X in DT)
    #print X,SETUP[X]+0,SUCC[X]+0,substr(SUCC[X]/SETUP[X]*100,0,5),FWD[X]+0,TIME[X]+0,MISS[X]+0 #Old way ->  Works
    perc = div(SUCC[X],SETUP[X]) #New Way  
    print X,SETUP[X]+0,SUCC[X]+0,perc,FWD[X]+0,TIME[X]+0,MISS[X]+0 #New Way  -> doesn't work

   }

Below is the output I get with both:

[root@decobox utils]# cat /opt/decobox/logs/manager.log|awk -f test.streamReport.awk|sort -M #Old way works, and gives full report
08/10/13,01,542,536,98.89,361,0,0
08/10/13,02,330,327,99.09,210,0,0
08/10/13,03,235,232,98.72,104,0,0
08/10/13,04,181,181,100,94,0,0
08/10/13,05,180,179,99.44,104,0,1
08/10/13,06,322,320,99.37,181,1,1
08/10/13,07,475,468,98.52,344,0,1
08/10/13,08,671,663,98.80,436,0,2
08/10/13,09,745,734,98.52,401,3,5
08/10/13,10,773,761,98.44,398,0,2
08/10/13,11,717,713,99.44,397,0,4
08/10/13,12,783,764,97.57,447,7,5
08/10/13,13,719,694,96.52,450,1,7
08/10/13,14,393,379,96.43,191,8,5
[root@decobox utils]# vim test.streamReport.awk
[root@decobox utils]# cat /opt/decobox/logs/manager.log|awk -f test.streamReport.awk|sort -M #New way only gives one line of output
08/10/13,06,322,320,99.37,181,1,1

I can't seem to figure out why this isn't working. I'm sure it's something simple, but I'm at a loss here.

Somewhat as an aside, how does my code look here? Is there anything obviously wrong, or things I could be doing better? I'm not sure that returning a value from a function instead of printing it is preferred in awk, but when I tried getting it to work by printing things out, it broke completely.

Guess you are missing the curly braces in the END block for for loop

...
END{
    for (X in DT) {
      #print X,SETUP[X]+0,SUCC[X]+0,substr(SUCC[X]/SETUP[X]*100,0,5),FWD[X]+0,TIME[X]+0,MISS[X]+0 #Old way ->  Works
      perc = div(SUCC[X],SETUP[X]) #New Way  
      print X,SETUP[X]+0,SUCC[X]+0,perc,FWD[X]+0,TIME[X]+0,MISS[X]+0 #New Way  -> doesn't work
    }
}

--ahamed

1 Like

Oh...son of a...seriously?

So how come I need this extra set of brackets now, but I don't need it when I forgo the function and just print the info I need? I'm trying to walk through this step by step based on what I understand of awk script structure, but it's just not adding up for me.

You can omit the { } braces after an if or a for if there is only one statement in it.
It has nothing to do with calling function.