如何测试 awk 中是否定义了函数?

如何测试 awk 中是否定义了函数?

我正在编写一个awk程序,我希望它可以使用 和 来运行mawkgawk。我需要一个排序功能。我已经编写了自己的函数,但我想使用内置asort()函数(gawk如果可用)。

我如何从程序内部知道该asort()功能是否可用?

更一般地说,如何测试某个功能(例如gensub())是否可用?

答案1

没有可移植的方法来测试 Awk 中是否存在函数。如果您从 shell 调用 Awk 脚本,则可以首先进行 Awk 调用来测试函数是否存在。

if awk 'BEGIN {asort(a)}' <>/dev/null 2>/dev/null; then
  define_asort=
else
  define_asort='
function asort() { … }
'
fi
awk "$define_asort"'
  … rest of script …
'

如果您只是想将 GNU Awk 与其他功能区分开来,您可以测试其他一些 GNU Awk 功能。在 Awk 中调用未定义的函数会导致致命错误,但使用未定义的变量总是没问题并返回空值。您特别可以使用PROCINFO[version],从 Gawk 3.1.4 开始,它包含 Gawk 版本号。

function my_sort(a) { … }
function sort_wrapper(a) { if (PROCINFO["version"]) asort(a); else my_sort(a); }

答案2

我可以建议一个 hack 来确定您是否正在运行mawkgawk.这里是

BEGIN {
  file = ARGV[0] " -W version 2>&1 | head -1"
  file | getline
  if ($1 == "mawk")
    print "mawk"
  else if ($2 == "Awk")
    print "gawk"
  close(file)
}

答案3

你可以这样做:

awk 'BEGIN {has_asort = (asort (x)) == "0"}
     function my_asort(a) {
       if (has_asort) return asort (a)
       ...
     }
     ...

asort请注意和之间的空格(x)很重要。有了它,在awk不支持 的实现中asort(),它被解释为asort连接到x1 的变量。如果没有它,您会收到有关该函数不存在的错误asort()

因此,我们可以asort()通过在未定义的数组上调用它来判断是否支持这里,x在这种情况下它返回0,而在awk不支持它的 s 中,这是两个未定义变量的串联,会产生空字符串。

答案4

以下适用于 Ubuntu 20.04 下的 gawk 5.0.1;嗯嗯:

#!/usr/bin/awk -f
@load "rwarray" # just to show how extensions look
function DoSomething(a, b){
  return a * b
}
BEGIN {
  PROCINFO["sorted_in"] = "@ind_str_asc" # options are @unsorted, @ind_str_asc, @ind_num_asc, @val_type_asc, @val_str_asc, @val_num_asc; also ..._desc
  for(_key in PROCINFO["identifiers"]){
    _val = PROCINFO["identifiers"][_key]
    if(_val ~ /scalar$/) { continue }
    if(_val ~ /array$/) { continue }
    if(_val ~ /untyped$/) { continue }
    if(_val ~ /builtin$/) { continue } # It Depends (tm) - do you want builtin functions or not?
    print _key " = " _val
  }
}

它打印:

DoSomething = user
reada = extension
writea = extension

或者

DoSomething = user
and = builtin
asort = builtin
asorti = builtin
atan2 = builtin
bindtextdomain = builtin
close = builtin
compl = builtin
cos = builtin
dcgettext = builtin
dcngettext = builtin
exp = builtin
fflush = builtin
gensub = builtin
gsub = builtin
index = builtin
int = builtin
isarray = builtin
length = builtin
log = builtin
lshift = builtin
match = builtin
mktime = builtin
or = builtin
patsplit = builtin
rand = builtin
reada = extension
rshift = builtin
sin = builtin
split = builtin
sprintf = builtin
sqrt = builtin
srand = builtin
strftime = builtin
strtonum = builtin
sub = builtin
substr = builtin
system = builtin
systime = builtin
tolower = builtin
toupper = builtin
typeof = builtin
writea = extension
xor = builtin

相关内容