shell function, system, awk

Hi all,

I am calling a shell function within awk using system. I am struggling to get my expected output:

#!/bin/sh

set -o nounset
BEG=44
END=55

shfun()
{
  echo "1|2|3"
}

export -f shfun
typeset -F > /dev/null

awk 'BEGIN {OFS="|"; print "'"$BEG"'",system( "shfun" ),"'"$END"'"}'
$ ./funcawk
1|2|3
44|0|55

But, I want the output as: (in the same line)

44|1|2|3|55

Please help

The function prints its output, including a trailing newline, when it is invoked. Then awk prints the result of its own print command. You need to capture the output from the shell function in awk, like with backticks in the shell. My first question would be whether you couldn't avoid this somehow.

If the output from the function is just a static string, it's really simple:

awk -v fun=`shfun` -v beg="$BEG" -v end="$END" 'BEGIN{OFS="|"; print beg fun end }'

... or if your awk doesn't understand -v, with direct interpolation of shell variables in the script itself like you already had.

era, thanks a lot for your valuable reply.

I have a query related to this

$ cat file.txt
AA
BB
CC
DD
$ cat my.sh
set -o nounset

diff=26
start=1

#Print random number between 1-30
f_random () {
        firstran=`echo $((RANDOM%$diff+$start))`
        second=`echo $((RANDOM%$diff+$start))`
        echo "$firstran|$second"
}

export -f f_random
typeset -F > /dev/null

awk -v fun=`f_random` 'BEGIN{OFS="|"}; {print $0,fun}' file.txt
$ ./my.sh
AA|14|3
BB|14|3
CC|14|3
DD|14|3

I expected it to print different set of random numbers for each record AA,BB,CC, DD , but its not printing.

Basically what I expected, execute my function f_random for each row in file.txt. As the volume of file.txt is huge, I can't make a normal for loop for this purpose.

It's only invoking the backtics once, so no surprise there. In this case, the text you want is not static, so the workaround doesn't work.

If your awk script is no more complex than this, why do you need awk in the first place? Also note that newer versions of awk have a built-in rand() function. Or if you don't have that, but are on a platform which offers /dev/random maybe you can use that from within awk instead.

awk can do more than simple one liners.

awk 'BEGIN{
 OFS="|"
 srand()
 top=26 
}
{
  print $0,int((rand() * top )),int((rand() * top ))
  
}' file

output:

# ./test.sh
AA|8|17
BB|5|10
CC|12|7
DD|3|5

era and ghostdog74 thanks a lot for your replies.