![Gawk:将数组传递给函数](https://linux22.com/image/31123/Gawk%EF%BC%9A%E5%B0%86%E6%95%B0%E7%BB%84%E4%BC%A0%E9%80%92%E7%BB%99%E5%87%BD%E6%95%B0.png)
坚持使用 GNU awk 3.1.6,并认为我已经解决了它的数组错误,但在 600 行 awk 程序中仍然存在看起来像范围的问题。需要验证对 awk 中数组范围的理解才能找到我的错误。
鉴于这个说明性的 awk 代码......
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
将打印...
global result
由于数组始终通过引用传递给函数,因此所有数组始终是全局的。无法创建本地数组。它是否正确?无法找到明确说明这一点的文档。
由于我正在调试,并且 3.1.6 本身在该领域存在已知的错误,因此我试图确定 awk 的错误从哪里开始,而我的错误从哪里开始。
补充:为什么 ga[] 在函数内部工作?
首先,将数组传递给函数foo(ga)
实际上是没有必要的。只需garray[]
在函数内部访问它即可。然而,这样做不会造成明显的性能损失,并且有助于调试和错误报告。
在 using 中foo(ga)
,ga[]
是全局数组的同义词garray[]
。它不是 的本地副本garray[]
,而只是指向 的指针garray[]
,就像符号链接是指向文件的指针一样,因此可以使用多个名称访问同一文件(或数组)。
补充:格伦·杰克曼答案的澄清
创建数组时外部函数对于该函数来说是全局的,可以传递给它或只是在其中引用,创建的数组里面函数确实保留在该函数的本地并且在其外部不可见。修改杰克曼先生的例子说明了这一点......
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before:
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after:
请注意,我们仅将x[]
数组(实际上只是指向它的指针)传递给bar()
.y[]
在我们进入函数之前,该数组甚至不存在。
但是,如果我们y[]
通过将其包含在bar()
参数列表中来声明,而不在函数外部为其分配任何内容,则在调用bar(x,y)
...后它就会变得可见。
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x,y)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before:
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello
最后,如果我们y[]
在函数外部创建数组并将其传递给bar(x,y)
,则split()
函数内部的赋值将替换该数组的元素...
awk '
function bar(x,y) {
split("hello world", y)
print "x[1] inside: " x[1]
print "y[1] inside: " y[1]
}
BEGIN {
x[1]="goodbye"
y[1]="howdy"
print "x[1] before: " x[1]
print "y[1] before: " y[1]
bar(x,y)
print "x[1] after: " x[1]
print "y[1] after: " y[1]
}
'
x[1] before: goodbye
y[1] before: howdy
x[1] inside: goodbye
y[1] inside: hello
x[1] after: goodbye
y[1] after: hello
答案1
函数参数是函数的局部参数。
awk '
function foo(x,y) {y=x*x; print "y in function: "y}
BEGIN {foo(2); print "y out of function: " y}
'
y in function: 4
y out of function:
如果传递给函数的值少于参数,则额外的参数将为空。有时您可能会看到类似这样定义的函数
function foo(a, b, c d, e, f) {...
其中空格后面的参数是局部变量,并不打算在调用时取值。
没有理由这不适用于本地数组:
awk '
function bar(x) {
split("hello world", x)
print "in: " x[1]
}
BEGIN {
x[1]="world"
bar()
print "out: " x[1]}
'
in: hello
out: world
答案2
这gawk 文档清楚地表明数组是通过引用传递的,并且没有记录的方法可以解决这个问题。该行为与 4.0.1 相同gawk
。
POSIX 指定该行为,所以我不希望您会发现任何awk
行为不同的实现。
如果您需要该功能,您可以使用perl
.perl
附带一个工具 ( a2p
) 将awk
脚本翻译为perl
.