便携式检查阵列

Ste*_*nny 5 array awk posix mawk gawk

Gawk 有“isarray”:

if (isarray(x))
  print "is array"
else
  print "is scalar"
Run Code Online (Sandbox Code Playgroud)

但是 Mawk 和 "gawk --posix" 不会:

fatal: function 'isarray' not defined
Run Code Online (Sandbox Code Playgroud)

这可能会导致问题:

x
x[1]
fatal: attempt to use scalar 'x' as an array
Run Code Online (Sandbox Code Playgroud)

或者:

x[1]
x
fatal: attempt to use array 'x' in a scalar context
Run Code Online (Sandbox Code Playgroud)

awk 可以在不使用“isarray”函数的情况下检测数组吗?

Sté*_*las 2

我也不认为这是可能的。

\n\n

但我要补充一点,对于 busybox awk,变量可以是数组和标量。在那里可以这样做:

\n\n
a = "foo"; a["foo"] = "bar"\n
Run Code Online (Sandbox Code Playgroud)\n\n

当变量被用作数组时,length()返回数组中的元素数量,即使它也被定义为标量(尽管您可以使用它length(var "")来获取标量的长度),除非该变量已被定义为数组。作为参数传递给函数并在那里分配为标量(可以被视为错误):

\n\n
$\xc2\xa0busybox awk \'BEGIN{a[1] = 1; a = "foo"; print length(a), length(a"")}\'\n1 3\n$\xc2\xa0busybox awk \'function f(x) {x = "xxx"; print x[1], length(x)}\n               BEGIN{a[1]=1; x = "yyy"; print a[1], length(a); f(a)}\'\n1 1\n1 3\n
Run Code Online (Sandbox Code Playgroud)\n\n

太糟糕了,否则很容易isarray()在那里定义一个函数。我们仍然可以判断一个变量是否是一个至少包含一个元素的数组

\n\n
function isnonemptyarray(x) {\n  return length(x) > 0 && length(x "") == 0\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

(假设变量尚未定义为数组和标量)

\n\n

无论如何,这是busybox awk具体的。length()不能可移植地用于数组。可以array_length()通过以下方式定义可移植函数:

\n\n
function array_length(a, tmp1, tmp2) {\n  tmp1 = 0\n  for (tmp2 in a) tmp1++\n  return tmp1\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

但它不能在非数组变量上移植使用。

\n

  • @Steven,busybox 是例外。nawk 的行为类似于 gawk(原始 awk 允许 `a=1;a[1]=1`,尽管这将 `a` 从标量提升为数组,但不允许 `a[1]=1; a=1`)。所以如果有人应该受到责备,那就是 a、w 和 k,而不是 gawk 的维护者。 (2认同)