0

Can someone see why I get

awk: cmd. line:8:   function mma(num) {
awk: cmd. line:8:   ^ syntax error
awk: cmd. line:8:   function mma(num) {
awk: cmd. line:8:                     ^ syntax error

from this script?

echo "0.24 0.21 0.22 1/1282 10953" | awk '{

  min=""
  max=""
  avg=""

  # find min, max, avg
  function mma(num) {
    if(min==""){min=max=$1};
    if($1>max) {max=$1};
    if($1<min) {min=$1};
    total+=$1;
    count+=1;
    avg=total/count;
  }

  mma($1)
  mma($2)
  mma($3)

  print avg, max, min
}'
7
  • There are few points to be noted here eg--> while loop doesn't have done in it to complete it's syntax. Commented May 25, 2018 at 11:49
  • 1
    Your function cannot be defined in an action from a (pattern){ action } rule of your awk script. Commented May 25, 2018 at 11:50
  • If you could show us sample input and sample output in CODE TAGS in your post we could try to help you more here. Commented May 25, 2018 at 11:55
  • @RavinderSingh13 thanks. Now fixed. Commented May 25, 2018 at 11:55
  • @SandraSchlichting, kindly post the expected output too in your post. Commented May 25, 2018 at 11:57

1 Answer 1

5

Definitions of functions can appear anywhere between the rules of an awk program. From the POSIX standard :

The awk language also provides user-defined functions. Such functions can be defined as:

function name([parameter, ...]) { statements }

A function can be referred to anywhere in an awk program; in particular, its use can precede its definition. The scope of a function is global. <snip> Function definitions can appear anywhere in the program where a pattern-action pair is allowed.

This means a valid awk program looks like :

( pattern1 ) { action1 }
function name([parameter, ...]) { statements }
( pattern2 ) { action2 }
...

In your original code, you wrote the incorrect

( pattern ) { function name([paramter, ...]) { statements }
             action }

So the corrected version of your awk part would be:

awk 'function mma(num) {
        if(min==""){min=max=$1};
        if($1>max) {max=$1};
        if($1<min) {min=$1};
        total+=$1;
        count+=1;
        avg=total/count;
     }
     { min=""; max=""; avg=""
       mma($1); mma($2); mma($3)
       print avg, max, min
     }'

update: from the comments, it might be more useful to use

awk '{ avg=($1+$2+$3)/3; min=avg; max=avg;
       min=($1<min) ? $1 : min; max=($1>max) ? $1 : max
       min=($2<min) ? $2 : min; max=($2>max) ? $2 : max
       min=($3<min) ? $3 : min; max=($3>max) ? $3 : max
       print avg,max, min } ' /proc/loadavg

However, this is questionable as taking the average of averages is very ...

Also interesting might be the sar command.

Sign up to request clarification or add additional context in comments.

11 Comments

@SandraSchlichting this works without errors on my side, I am however a bit puzzled what the code does or its intentions should be. As your function argument num is never used. By default, this will always return the first element of /proc/cpuinfo
Ok, so that might be the problem then. I though the arguments for a function could be anything. I just called it num and thought it would be $1 inside the function definition. But that is not the case?
So I guess all $1 in the function should be num?
$i always refers to field number i.
@SandraSchlichting could you please explain your intentions for this script. Since /proc/loadavg shows the average load for the first 1,5 and 10 minutes of the system. Do you want to find the min/max/avg of these 3 numbers? Or do you want to have the min/max/avg per field of the continuously updated /proc/loadavg. If the latter, then this script will not work as intended.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.