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[]
関数内からアクセスするだけです。ただし、それを実行しても測定可能なパフォーマンスの低下はなく、デバッグとエラー報告に役立ちます。
を使用する場合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