shellmacrosawkcommandmawk

How to define new commands or macros in awk


I like to define a new command that wraps an existing awk command, such as print. However, I do not want to use a function:

#wrap command with function
function warn(text) { print text > "/dev/stderr" }
NR%1e6 == 0 {
  warn("processed rows: "NR)
}

Instead, I like to define a new command that can be invoked without brackets:

#wrap command with new command ???
define warn rest... { print rest... > "/dev/stderr" }
NR%1e6 == 0 {
  warn "processed rows: "NR
}

One solution I can imagine is using a preprocessor and maybe setting up the shebang of the awk script nicely to invoke this preproccessor followed by awk. However, I was more hoping for a pure awk solution.

Note: The solution should also work in mawk, which I use, because it is much faster than vanilla GNU/awk.

Update: The discussion revealed that gawk (GNU/awk) can be quite fast and mawk is not required.


Solution

  • You cannot do this within any awk and you cannot do it robustly outside of awk without writing an awk language parser and by that point you may as well write your own awk-like command which then would actually no longer really be awk in as much as it would not behave the same as any other command by that name.

    It is odd that you refer to GNU awk as "vanilla" when it has many more useful features than any other currently available awk while mawk is simply a stripped down awk optimized for speed which is only necessary in very rare circumstances.