5

I'm seeking a way to call an awk function by name, i.e. by using a string that is user input.

My goal is to replace a lot of code like this...

if (text == "a") a(x)
if (text == "b") b(x)
if (text == "c") c(x)

... with any kind of way to dispatch to the function by using the string name something like this:

send(text, x)

In other languages, this kind of effect is sometimes described as reflection, or message sending, or dynamic dispatch, or getting a function pointer by name.

I'm looking for a way to do this using gawk and ideally also using POSIX portable awk.

joelparkerhenderson
  • 34,808
  • 19
  • 98
  • 119
  • A workaround could be, tointegrate the AWK script into a BASH script, and insert the name of the function to be called though a BASH variable, roughtly like this: `awk '{ print '"$fun_name"'() }'`. This is much less powerful of course. – hoijui Apr 15 '23 at 17:31
  • A more powerful workaround would be, to use scripts instead of functions, and call them with `system(script_name)`. – hoijui Apr 15 '23 at 17:33

2 Answers2

9

Using GNU awk 4.0 or later for Indirect Function Calls:

$ cat tst.awk
function foo() { print "foo() called" }
function bar() { print "bar() called" }

BEGIN {
    var = "foo"
    @var()

    var = "bar"
    @var()
}

$ awk -f tst.awk
foo() called
bar() called
Ed Morton
  • 188,023
  • 17
  • 78
  • 185
  • 1
    Thanks Ed, this is perfect. Do you have advice for how to do it using pure POSIX, not gawk? (For this script, POSIX portability is a goal within a few months). – joelparkerhenderson Oct 26 '15 at 01:10
  • 4
    Yes, wait 5 years for POSIX to catch up with gawk :-). No, sorry, there's no good way to do it in POSIX. – Ed Morton Oct 26 '15 at 01:12
3
#!/usr/bin/awk -f
func alpha() {
  print "bravo"
}
BEGIN {
  charlie = "alpha"
  @charlie()
}

Output:

bravo

GNU awk - Git Repositories

Zombo
  • 1
  • 62
  • 391
  • 407