如何获取awk中数组的长度?


68

这个命令

echo "hello world" | awk '{split($0, array, " ")} END{print length(array) }'

对我不起作用,并显示此错误消息

awk:第1行:对数组array的非法引用

为什么?


2
实际上,您的代码对我有用,并按预期返回2。
dying_sphynx 2012年

5
它适用于gawkPOSIXawk或,但不适用gawk --posix
nwk

Answers:


100

拆分数组时,将返回元素数,因此您可以说:

echo "hello world" | awk '{n=split($0, array, " ")} END{print n }'
# ------------------------^^^--------------------------------^^

输出为:

2

1
我以前使用过split(),但从未意识到它返回了值!
bgStack15 '19

@ bgStack15惊喜!..是的,还有什么方便的价值。另外,我认为您会发现awk中的大多数函数都返回一些值,可能是针对错误建模的c语言0,或者一些非零值作为有用信息返回。祝好运!
剥壳机

39

文蒂米利亚先生的职能需要稍作调整才能完成这项工作(有关说明,请参见分号):

function alen(a, i) {
    for(i in a);
    return i
}

但是,不要在所有情况下都工作。这是因为awk存储和“查看”数组索引的方式:它们是关联的,不一定是连续的(如C。)因此,i不返回“ last”元素。

要解决此问题,您需要计算:

function alen(a, i, k) {
    k = 0
    for(i in a) k++
    return k
}

并且,以这种方式,请注意“一维”数组的其他索引类型,其中索引可能是字符串。请参阅:http : //docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm。有关“多维”数组和任意数组,请参见http://www.gnu.org/software/gawk/manual/html_node/Walking-Arrays.html#Walking-Arrays


24

我不认为这个人在问,“如何分割字符串并获取结果数组的长度?” 我认为他们提供的命令只是发生这种情况的一个例子。特别是,我认为这个人在问:1)为什么length(array)会引发错误,以及2)如何获取awk中数组的长度?

第一个问题的答案是,尽管在GNU awk(gawk)和其他一些变体中,长度函数对POSIX标准awk中的数组不起作用。第二个问题的答案是(如果我们想要一个适用于awk所有变体的解决方案)进行线性扫描。

例如,如下函数:

function alen (a,     i) {
    for (i in a);
    return i;}

注意:第二个参数我值得解释。

在awk中引入局部变量的方式是作为额外的函数参数,惯例是通过在这些参数之前添加额外的空格来表明这一点。这是在GNU awk中手动讨论在这里


2
好点。我的目的是使用OP的条款来回答原始问题。awk '{split($0, array, " ")}...',因此也是我的答案,取材自split原始的“ Awk编程语言”。祝你们好运。
剥壳机

谢谢。我并不想让我的答案这么笨拙。我有点着急。也许我会软化它。
David A. Ventimiglia

3
但是所有这些都是返回数组的第一个索引吗?另外,POSIX并未指定数组迭代的顺序。
osvein

第二个问题的答案是(如果我们想要一个可以在awk的所有变体中使用的解决方案) [是]进行线性扫描并计算并返回给定数组中元素的数量:... { for(i in a) c++; return c }
James Brown

1
哦,不是。该答案的修订版4或6不会真正返回数组的长度,而只会返回其随机最后一个索引。
罗兰·伊利格

18

只想指出:

  • 不需要存储split函数的结果即可打印。
  • 如果未为分隔提供分隔符,则将使用默认值FS(空白)。
  • END部分在这里没有用

    echo 'hello world' | awk '{print split($0, a)}'
    

15

gawk您可以使用功能length()

$ gawk 'BEGIN{a[1]=1; a[2]=2; a[23]=45; print length(a)}'
3

$ gawk 'BEGIN{a[1]=1; a[2]=2; print length(a); a[23]=45; print length(a)}'
2
3

GNU Awk用户指南中

使用gawk和其他几个awk实现,给定数组参数时,该length()函数将返回array中元素的数量。(ce)这比起初看起来没有用,因为不能保证将数组从一个索引到其中的元素数。如果在命令行上提供了--lint(请参阅选项),则gawk警告传递数组参数是不可移植的。如果提供了--posix,则使用数组参数是一个致命错误(请参阅数组)。


1
我认为大多数流行的awks都支持此功能,而不仅限于gawk。我在macOS和NetBSD上尝试了awk,两者都可以工作。
南晓

2

在MacOSX Lion上显示示例以显示使用的端口(输出可以是192.168.111.130.49704或:: 1.49704):

   netstat -a -n -p tcp | awk '/\.[0-9]+ / {n=split($4,a,"."); print a[n]}'

在此示例中,将打印第4列的最后一个数组项:“ 49704”



-2
echo "hello world" | awk '{lng=split($0, array, " ")} END{print lng) }'
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.