Atascado con GNU awk 3.1.6 y creo que he solucionado los errores de su matriz, pero todavía tengo lo que parece un problema de alcance en un programa awk de 600 líneas. Necesito verificar la comprensión del alcance de la matriz en awk para encontrar mi error.
Dado este código awk ilustrativo ...
function foo(ga) {
ga[1] = "global result"
}
garray[1] = "global"
foo(garray)
print garray[1]
imprimirá ...
global result
Dado que las matrices siempre se pasan a las funciones por referencia, todas las matrices son siempre globales. No hay forma de crear una matriz local. ¿Es esto correcto? No he podido encontrar documentos que explícitamente digan eso.
Desde que estoy depurando, y 3.1.6 en sí mismo tiene errores conocidos en esta área, estoy tratando de determinar dónde dejan los errores de awk y dónde comienza el mío.
Suplementario: ¿Por qué ga [] funciona dentro de la función entonces?
En primer lugar, pasar la matriz a la función con foo(ga)
es realmente innecesario. Simplemente acceda a él como garray[]
dentro de la función. Sin embargo, no hay una penalización de rendimiento mensurable al hacerlo, y ayuda en la depuración y la notificación de errores.
Al usar foo(ga)
, ga[]
es sinónimo de la matriz global garray[]
. En lugar de ser una copia local de garray[]
, es simplemente un puntero a garray[]
, más bien como un enlace simbólico, es un puntero a un archivo y, por lo tanto, se puede acceder al mismo archivo (o matriz) con más de un nombre.
Suplementario: aclaración de la respuesta de Glenn Jackman
Si bien las matrices creadas fuera de una función son globales para la función y pueden pasarse a ella o simplemente referenciarse dentro de ella, las matrices creadas dentro de una función de hecho permanecen locales a la función y no son visibles fuera de ella. La modificación del ejemplo del Sr. Jackman ilustra esto ...
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:
Tenga en cuenta que solo estamos pasando la x[]
matriz (en realidad, solo un puntero) bar()
. La y[]
matriz ni siquiera existe hasta que entramos en la función.
Sin embargo, si declaramos y[]
al incluirlo en la bar()
lista de argumentos sin asignarle nada fuera de la función, se hace visible después de llamar 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
Finalmente, si creamos la y[]
matriz fuera de la función y la pasamos bar(x,y)
, la split()
asignación dentro de la función reemplaza los elementos de esa matriz ...
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