Problem using function in awk


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Problem using function in awk
# 8  
Old 09-05-2010
It might because in function rgaussian11 the variables mean and sigma are local variables, however, a and b are defined in the function body and therefore global, so your values outside and inside the function get mixed up...
# 9  
Old 09-05-2010
Can't reproduce your error. It works as expected for me.

Code:
$ 
$ 
$ cat gaussian1.sh
##
awk '
  function rgaussian1() {
      a = rand()
      b = rand()
      c = rand()
      r1 = a + b + c
      return r1
  }
  function rgaussian11(mean, sigma) {
      print "(1)  VALUES: ",mean,sigma
      a = rgaussian1()
      b = mean + (a * sigma)
      print "(2)  VALUES: ",mean,sigma
      return b
  }
  BEGIN {
      srand()
      a = 5
      b = 0.5
      x = rgaussian11(a, b)
      print x
  }'
$ 
$ 
$ . gaussian1.sh
(1)  VALUES:  5 0.5
(2)  VALUES:  5 0.5
5.73322
$ 
$ 
$ . gaussian1.sh
(1)  VALUES:  5 0.5
(2)  VALUES:  5 0.5
5.99618
$ 
$ . gaussian1.sh
(1)  VALUES:  5 0.5
(2)  VALUES:  5 0.5
6.01297
$ 
$ . gaussian1.sh
(1)  VALUES:  5 0.5
(2)  VALUES:  5 0.5
5.27391
$ 
$ . gaussian1.sh
(1)  VALUES:  5 0.5
(2)  VALUES:  5 0.5
5.56646
$ 
$ 

tyler_durden
# 10  
Old 09-05-2010
Data

Have put this but results are still wrong. Totally confused now.

Code:
  function rgaussian1() {
      a = rand()
      b = rand()
      c = rand()
      r1 = a + b + c
      return r1
  }

  function rgaussian11(mean, sigma) {
      print "VALUES: ",mean,sigma
      a = rgaussian1()
      r1 = mean + (a * sigma)
      return r1
  }

  BEGIN {
      srand()
  }

# Include gaussian distributed random numbers
  NF == 2 {
      a = 5
      b = 0.5
      r1 = rgaussian1()
      r2 = rgaussian11(a,b)
      print a,b
  }

Code:
VALUES:  0.60164 0.155695
1.92518 0.615652
VALUES:  0.0518825 0.208599
1.84557 0.612806
VALUES:  0.854148 0.27189
1.72343 0.0530989

# 11  
Old 09-05-2010
By default variables in awk are global. The problem is that in the 'body' a is assigned 5, and from appearances the value of a should still be 5 when rgaussian11(a,b) is invoked. However, rgaussian1() sets a and thus it is not.

In awk, it is possible to declare a variable as local to a function. It is done by defining it as an argument, and convention is to separate the local variables with a tab to make it more obvious that the function is not expecting them to be passed in. For instance, your function should be defined like this:

Code:
function rgaussian1(            a, b, c, r1 )

This declares a,b,c and r1 as local variables. If this is done, the value of a in the 'body' of the programme is unchanged.

---------- Post updated at 17:16 ---------- Previous update was at 17:13 ----------

As an afterthought, you might declare your other function in a similar fashion:

Code:
 function rgaussian11(mean, sigma,         a, b )

Declaring both variables a and b as local to the function.
# 12  
Old 09-05-2010
Or use vars with different names or skip the intermediate vars altogether, e.g.:
Code:
  function rgaussian1() {
    return rand() + rand() + rand()
  }

  function rgaussian11(mean, sigma) {
      print "VALUES: ",mean,sigma
      return mean + (rgaussian1() * sigma)
  }

# 13  
Old 09-05-2010
That's what I want them to be, local to the function as you say. I thought that as I do not want to return their values, I would not include them as function parameters.

---------- Post updated at 04:30 PM ---------- Previous update was at 04:19 PM ----------

Thanks a lot. I did not know this detail of how to define local variables in functions, by declaring all local function variables in the formal declaration of the function.
# 14  
Old 09-05-2010
Quote:
Originally Posted by kristinu
That's what I want them to be, local to the function as you say. I thought that as I do not want to return their values, I would not include them as function parameters.
What you return, using the 'return' statement has nothing to do with the values that are declared as parameters in the function header. Anything referenced in the header is considered local and changes to those variables does not affect the global copy of a variable with the same name.

Consider this small example:
Code:
#!/usr/bin/env ksh
awk '
        function demo( a, b,    c, d )       # the spacing suggests a and b are expected parameters, c and d are local variables
        {
                a += 1;               # do some work -- change the value of a
                c = a+b;
                d = a-b-1;
                e = a*b;
                printf( "in demo: a=%d  b=%d  c=%d d=%d e=%d\n", a, b, c, d, e );
        }

        BEGIN { 
                a = 2;
                b = 3;
                demo( a, b )
                printf( "in begin: a=%d  b=%d  c=%d d=%d e=%d\n", a, b, c, d, e );
        }
'

When executed, the output is this:

Code:
in demo: a=3  b=3  c=6 d=-1 e=9
in begin: a=2  b=3  c=0 d=0 e=9

The variable 'e' is not referenced in the function header and thus remains 9 after the call to the function demo(). Variable 'a', even though changed in the function, has the original value after the call, as do b, c and d.

One of the most common, and frustrating, mistakes when writing awk programmes is to invoke a function from inside a for loop using 'i' as the index variable only to have it changed unintentionally by the called function.

---------- Post updated at 17:37 ---------- Previous update was at 17:35 ----------

Oops -- looks like we crossed our posts, extra explanation never hurts though Smilie
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Need help on awk for printing the function name inside each function

Hi, I am having script which contains many functions. Need to print each function name at the starting of the function. Like below, functionname() { echo "functionname" commands.... } I've tried like below, func=`grep "()" scriptname | cut -d "(" -f1` for i in $func do nawk -v... (4 Replies)
Discussion started by: Sumanthsv
4 Replies

2. Shell Programming and Scripting

Function problem

hey guys, im trying to learn bourne shell atm and I'm having some issues with functions. so heres my code: #!/bin/bash ##functions memory () { free -m } space () { df -h } ip () { (5 Replies)
Discussion started by: hawkfro12
5 Replies

3. UNIX for Dummies Questions & Answers

Explanation on problem "match" function awk

Hello Unix experts, If I could get any explanations on why the code below doesn't work it would be great ! My input looks like that ("|" delimited): Saaaaabbbbbccccc|ok Sdddddfffffggggg|ok The goal is, if $2 is "ok", to remove everything before the pattern given in the match function... (5 Replies)
Discussion started by: lucasvs
5 Replies

4. Shell Programming and Scripting

AWK Problem in recursive function

Hi, I have a file like this SPF_HC00001|iCalcular_Monto_Minimo|--->|SPF_HC00028|pstcObtener_Monto_Minimo SPF_HC00004|iCalcular_Incrementos|--->|SPF_HC00032|pstcObtener_Num_Incrementos SPF_HC00005|iCalcular_Articulo_167_Reformado|--->|SPF_HC00031|pstcObtener_Por_CB_Inc... (2 Replies)
Discussion started by: kcoder24
2 Replies

5. UNIX for Advanced & Expert Users

AWK sub function curious problem under bash

I need to detect the number of pages in a print job when it is available so I can warn users when they try to print a report much larger than they expected. Sometimes they are trying to print 1000 page reports when they thought they were getting a 10 page report. Under linux I am scanning the... (5 Replies)
Discussion started by: Max Rebo
5 Replies

6. Shell Programming and Scripting

splice function problem

Hi All, I am using splice function in for loop to delete particular element from array with one condition. my $cnt=0; foreach my $elem (@result) { if (condition){ splice(@result, $cnt, 1);} else{ $cnt++;} } Now when in array, two elements comes sequentially with the... (3 Replies)
Discussion started by: gentleDean
3 Replies

7. Shell Programming and Scripting

Awk problem: How to express the single quote(') by using awk print function

Actually I got a list of file end with *.txt I want to use the same command apply to all the *.txt Thus I try to find out the fastest way to write those same command in a script and then want to let them run automatics. For example: I got the file below: file1.txt file2.txt file3.txt... (4 Replies)
Discussion started by: patrick87
4 Replies

8. Shell Programming and Scripting

awk , function call problem

#!/bin/bash awk ' function ad(t,r){ return (t+r); } BEGIN{ print ad(5,3); } { print ad(5,3); } ' Doesn't print anything for the last print ad(5,3); (6 Replies)
Discussion started by: cola
6 Replies

9. Shell Programming and Scripting

problem in awk int() function

awk -vwgt=$vWeight -vfac=$vFactor ' BEGIN { printf("wgt:" wgt "\n"); printf("factor:" fac "\n"); total = sprintf("%.0f", wgt * fac); total2 = sprintf("%.0f", int(wgt * fac)); printf("total:" total "\n"); printf("total2:" total2 "\n"); } ' if vWeight=326.4 vFactor=100 the result... (2 Replies)
Discussion started by: qa.bingo
2 Replies

10. Programming

Problem with aio_write() function

Hello, How to execute a call back function after aio_write() or aio_read() in Sun Solaris 5.7? I have filled the control block struct aiocb as follows: aio_sigevent.sigev_signo = SIGEV aio_sigevent.sigev_notify = SIGEV_THREAD Then I have filled the call back function in ... (0 Replies)
Discussion started by: hmurali
0 Replies
Login or Register to Ask a Question