2017-06-13 16 views
1

AWK再帰パズルを解き明かします。AWK: "数値列"ではなく "配列"として初期化されていない変数を強制/キャスト

私は配列を埋めなければならない再帰的な作業があります。しかし、私はただパラメータとして配列を渡す必要があります。再帰が配列を塗りつぶします。これを行うためには、再帰呼び出しは配列の長さを知る必要があるので、配列の最後に追加することができます。

唯一の問題は、パラメータ上で関数を実行した後で配列の最初の要素を埋めることができないことです。length()isarray()は未知のパラメータで実行されているため、スカラー型になっているようです。

だから、長さを使う前に初めて配列に追加するかどうかを知るには何か方法が必要です。私はむしろ、再帰の深さを記録する余分なパラメータを渡すことはなく、配列が空であるか論理的でないかをコードに伝えます。しかし、私はこの回避策を知っています。ここで


は、問題の最小検証例です。


最小検証例:

#! /bin/awk -f 
BEGIN{ 
    test(x) 
} 

function test(x, y){ 
    y = length(x) 
    x[1] = 1   # <- fatal: attempt to use scalar parameter as an array 
} 

一方、この作品:

#! /bin/awk -f 
BEGIN{ 
    test(x) 
} 

function test(x, y){ 
    # y = length(x) 
    x[1] = 1   # <- now it works 
} 

初期化されていない変数の長さにアクセスできるようにする必要があります(再帰では一般的に初期化されますが、最初はそれはありません)。スカラー型である。私は、配列に「長さ」のインデックスを格納する回避策を認識しています。

awkでこの機能をどのように達成できますか?

答えて

2

これはあなたが望むものであるようですね。それは前にタイプされていなかった場合、私はそのx AWK言っていますxに配列演算子(in)を使用することにより

$ cat tst.awk 
BEGIN{ 
    test(x) 
    print "done" 
} 

function test(x, y,i){ 
    for (i in x) { 
     ++y 
    } 
    x[y+1] = 1 
} 

$ awk -f tst.awk 
done 

は、アレイとそうです(何初期化されていないと参照している場合)、その時点で配列として型指定されます。

length()を使用しているのは、文字列と配列の両方で呼び出すことができ、デフォルトでは文字列とみなされているため、xを文字列として入力していました。 isarray()を使用するとxは配列として認識されます。xは、長さ()と同じように最初に配列として入力されます。isarray(x)xと入力するとどちらの型の引数でもかまいません。

+0

興味深い!関数本体で 'x [y + 1]'文 'length(x)'が失敗した後でも;私が推測するいくつかの変なこと。 – karakfa

+0

ここにあります:https://stackoverflow.com/q/44529958/1435869 – karakfa

関連する問題