AWK (igawk) @include statement fails

321 Views Asked by At

Here’s what I’m currently trying as a base case with the function definition written manually (which works):

igawk 'function tripleit(x) {return x*3} {print tripleit($1)}' <(echo 5)

Here is a theoretically more practical version calling a function library (which fails):

igawk '@include $HOME/code/thefunc {print tripleit($1)}' <(echo 5)

Here's "thefunc" :

function tripleit(x){return x*3}

If anyone knows HOW or WHY this is failing, and how I can get something like this to work, it would be super-helpful. I love AWK, but I'm not about to type and retype UDFs each and every time I need them.

I have tried to create foo.awk: function foo(){print "Hello World"}

And call this as suggested:

$ cat foo.awk
function foo(){print "Hello World"}
$ igawk '@include "foo.awk"; BEGIN{foo()}'
igawk:/dev/stdin:0: cannot find "foo.awk";
$ igawk '@include "$PWD/foo.awk"; BEGIN{foo()}'
$ igawk '@include "./foo.awk"; BEGIN{foo()}'
$

No output yet.

2

There are 2 best solutions below

0
Ed Morton On BEST ANSWER

awk has no idea what the shell variable $HOME contains and @include requires a string as it's argument.

$ cat foo.awk
function foo() {
    print "Hello World"
}

$ gawk '@include $PWD/foo.awk; BEGIN{foo()}'
gawk: cmd. line:1: @include $PWD/foo.awk; BEGIN{foo()}
gawk: cmd. line:1:          ^ syntax error

$ gawk '@include "$PWD/foo.awk"; BEGIN{foo()}'
gawk: cmd. line:1: error: can't open source file `$PWD/foo.awk' for reading (No such file or directory)

$ gawk '@include "./foo.awk"; BEGIN{foo()}'
Hello World

You can also use AWKPATH instead of explitly providing the library directory path every time:

$ echo "$AWKPATH"

$ gawk '@include "foo.awk"; BEGIN{foo()}'
Hello World

$ mkdir blob

$ mv foo.awk blob

$ gawk '@include "foo.awk"; BEGIN{foo()}'
gawk: cmd. line:1: error: can't open source file `foo.awk' for reading (No such file or directory)

$ AWKPATH="$PWD/blob:$AWKPATH" gawk '@include "foo.awk"; BEGIN{foo()}'
Hello World

alternatively try:

gawk -f foo.awk -f - <<<'BEGIN{foo()}'
0
wef On

(plopping this here in case I run into this again ...)

It took me some fiddling about to get this right, but you can encode AWKPATH (or any other environment variable) into any script like this:

#!/usr/bin/env -S AWKPATH=${HOME}/bin awk -f
@include "utilities.awk"
...

Don't forget to chmod +x the script.

The tricky part was the man page documentation for -S which says

-S, --split-string=S

which seems to imply the following (which fails):

#!/usr/bin/env -S AWKPATH=${HOME}/bin awk -f