我正在编写一个awk
程序,我希望它可以使用 和 来运行mawk
它gawk
。我需要一个排序功能。我已经编写了自己的函数,但我想使用内置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 来确定您是否正在运行mawk
或gawk
.这里是
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
连接到x
1 的变量。如果没有它,您会收到有关该函数不存在的错误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