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

时间:2012-02-19 18:28:38

标签: awk

此命令

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

对我不起作用并提供此错误消息

  

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

为什么?

9 个答案:

答案 0 :(得分:80)

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

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

输出是:

2

答案 1 :(得分:36)

先生。 Ventimiglia的功能需要稍微调整才能完成工作(请参阅for语句中的分号):

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

答案 2 :(得分:21)

我不认为这个人在问,“我如何拆分字符串并得到结果数组的长度?”我认为他们提供的命令只是它出现的情况的一个例子。特别是,我认为这个人在问1)为什么长度(数组)会引发错误,2)如何在awk中得到数组的长度?

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

例如,像这样的函数:

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

注意:第二个参数我需要一些解释。

在awk中引入局部变量的方式是作为额外的函数参数,约定是通过在这些参数之前添加额外的空格来指示这一点。这在GNU Awk手册here中进行了讨论。

答案 3 :(得分:15)

只想指出:

  • 不需要存储split功能的结果才能打印出来。
  • 如果未为拆分提供分隔符,则将使用默认的FS(空格)。
  • 此处END部分无用

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

答案 4 :(得分:8)

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

来自The GNU Awk user's guide

  

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

答案 5 :(得分:2)

Mac OSX 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”

答案 6 :(得分:0)

这是我获取数组长度的一种快速方法,如果不存在则将长度初始化为零,但不要覆盖任何现有数组或意外添加额外元素:

(g/mawk) 'function arrayinit(ar, x) { for(x in ar) {break}; return length(ar) };

for 循环基本上有 O(1),因为它在任何现有元素上退出,而不管排序顺序。我的旧方法用于测试或拆分空字符串。这种方式节省了拆分步骤,因为 for 循环可能隐式地使用该函数。

这也适用于像 arr[x,y] 或 gawk arr[x][y] 这样的伪多维数组,而不必担心“x”是否是 gawk 意义上的子数组。

答案 7 :(得分:-1)

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

答案 8 :(得分:-1)

如果您不使用gawk,请尝试此操作。

awk 'BEGIN{test="aaa bbb ccc";a=split(test, ff, " "); print ff[1]; print a; print ff[a]}'

输出:

aaa
3
ccc

8.4.4使用split()创建数组http://docstore.mik.ua/orelly/unix/sedawk/ch08_04.htm