3

我正在为二维数组尝试一个简单的 awk 脚本,如下所示:

BEGIN{
     b[1][1]=0
     split("5 4 3 2",b[1])
     print b[1][1]
}

这个代码片段也在 gnu gawk 教程中提到。但是当我尝试运行它时,我得到了 b 索引的语法错误。谁能告诉问题是什么?在 gnu 教程中,他们显示了输出。

4

1 回答 1

7

更新

Normalawk使用b[1,1]语法,但它不是真正的二维数组。而是一个哈希,具有像1 SUBSEP 1. 因此,如果您使用for (i in b) print i,那么您将拥有这样的索引。默认值为SUBSEP0x34,但可以重新定义。

split无法定义数组元素。但是你可以移动到一个普通的变量并b用一个 for 循环填充。我们试试看:

BEGIN{
     #b[1,1] is automatically created if referenced, even by a read.
     split("5 4 3 2",b[1]);
     print b[1,1];
}

说:“awk:./x.awk:5:致命:拆分:第二个参数不是数组”

下次尝试:

BEGIN{
     split("5 4 3 2",a);
     b[1] = a;
     print b[1,1];
}

没有。错误:“awk:./x.awk:5:致命:尝试在标量上下文中使用数组‘a’”

您可以使用什么将拆分结果存储在数组中,然后将其复制到 2D 中,例如 stuct:

BEGIN{
     split("5 4 3 2",a);
     for(i in a) b[1,i]=a[i];
     print b[1,1];
}

请注意,这b不是真正的二维数组。现在它有 4 个这样的元素:b[1 SUBSEP 1] == 5, b[1 SUBSEP 2] == 4&c。

如果您想转储 be 的值,您可以创建两个或一个循环,例如:

for (i in b) print i" => "b[i];

输出:

11 => 5
12 => 4
13 => 3
14 => 2

如果您想查看分隔符,请将其设置为可见的内容:

BEGIN{
     SUBSEP=":"
     split("5 4 3 2",a);
     for(i in a) b[1,i]=a[i];
     print b[1,1];
     print b[1 SUBSEP 1];
     for (i in a) print "a-"i" => "a[i];
     for (i in b) print "b-"i" => "b[i];
}

输出:

5
5
a-4 => 2
a-1 => 5
a-2 => 4
a-3 => 3
b-1:1 => 5
b-1:2 => 4
b-1:3 => 3
b-1:4 => 2

如您所见,哈希元素未按数字顺序打印。我很惊讶以b这种方式打印。但是你不能相信这个(见a元素)。

添加

我检查了 3.1.5,b[1][1]andsplit("5 4 3 2",b[1])符号不起作用(如预期的那样)。我还尝试了 4.1.0 并且两者都在工作!似乎在较新的b[1][1]=0定义了一个数组,b[1]所以split("5 4 3 2",b[1])可以工作。但b[1,1]=0表现不同。它以旧方式运行,因此b[1]不是真正的数组(因为没有这样的元素,而是b[1 SUBSEP 1])。

因此,请尝试检查版本并使用旧语法,因为您的awk --version似乎对于新语法来说太旧了。

于 2013-04-17T05:31:34.027 回答