awkで関数が定義されているかどうかをテストする方法は?

awkで関数が定義されているかどうかをテストする方法は?

プログラムを書いていawkます。ソート機能が必要です。独自の関数を作成しましたが、可能であれば組み込み関数を使用したいと思います。mawkgawkasort()gawk

asort()この機能が利用可能かどうかをプログラム内でどのように知ることができますか?

gensub()より一般的には、特定の機能(例:)が利用可能かどうかをどのようにテストしますか?

答え1

Awkに関数が存在するかどうかをテストするための移植可能な方法はありません。シェルから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で未定義の関数を呼び出すと致命的なエラーが発生しますが、未定義の変数を使用すると常に問題はなく、NULL値を返します。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

実行中であることを確認するためにハッキングを提案でき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サポートされていない実装では、1に関連付けられた変数asort()として解釈されます。それ以外の場合、関数が存在しないというエラーが発生します。asortxasort()

したがってasort()、未定義の配列から呼び出すことでこれがサポートされているかどうかがわかります。xこの場合は返します0が、awkそれをサポートしていないsでは、未定義の2つの変数を連結してnull文字列が生成されます。

答え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

関連情報