AWKでこのような配列を初期化することは可能ですか?
Colors[1] = ("Red", "Green", "Blue")
Colors[2] = ("Yellow", "Cyan", "Purple")
次に、Colors [2,3] = "Purple"の2次元配列を作成します。
別のスレッド 私はそれが不可能であることを理解しています(「残念なことに、split()を乱用せずに一度に配列を設定する方法はありません」)。とにかく、私は100%確信したいと思います、そして、私は同じ質問の他のものがいると確信しています。
上記のような配列を初期化する最も簡単な方法を探していますが、うまく書かれているといいでしょう。
答えてくれてありがとう。とにかく、一次元配列を初期化したい人のために、ここに例があります:
SColors = "Red_Green_Blue"
split(SColors, Colors, "_")
print Colors[1] " - " Colors[2] " - " Colors[3]
2次元配列は簡単に作成できます。あなたができないことは、私の知る限り、1回の操作で初期化することです。 dmckee のヒントのように、配列を初期化できない理由の1つは、添え字のタイプに制限がないため、純粋な数値である必要がないことです。以下のスクリプトのように、複数の割り当てを行うことができます。添え字は、変数SUBSEPで指定された不明瞭な文字で正式に区切られ、デフォルト値は034(U + 001C、FILE SEPARATOR)です。明らかに、インデックスの1つにこの文字が含まれている場合、混乱が続きます(ただし、文字列でその文字を最後に使用したのはいつですか?)。
BEGIN {
Colours[1,1] = "Red"
Colours[1,2] = "Green"
Colours[1,3] = "Blue"
Colours[2,1] = "Yellow"
Colours[2,2] = "Cyan"
Colours[2,3] = "Purple"
}
END {
for (i = 1; i <= 2; i++)
for (j = 1; j <= 3; j++)
printf "Colours[%d,%d] = %s\n", i, j, Colours[i,j];
}
実行例:
$ awk -f so14063783.awk /dev/null
Colours[1,1] = Red
Colours[1,2] = Green
Colours[1,3] = Blue
Colours[2,1] = Yellow
Colours[2,2] = Cyan
Colours[2,3] = Purple
$
_GNU awk
_がある場合、 true多次元配列 を使用できます。この回答ではsplit()
関数を使用していますが、ほとんど間違いなくこれを悪用しません。次のように実行します:
_awk -f script.awk
_
_script.awk
_の内容:
_BEGIN {
x=SUBSEP
a="Red" x "Green" x "Blue"
b="Yellow" x "Cyan" x "Purple"
Colors[1][0] = ""
Colors[2][0] = ""
split(a, Colors[1], x)
split(b, Colors[2], x)
print Colors[2][3]
}
_
結果:
_Purple
_
既存の回答は役に立ち、すべての側面を網羅していますが、より焦点を絞った要約を提供したいと思いました。
質問は2つの側面を複雑にします。
Awkにはno配列リテラル(初期化子)構文があります。
最も単純な回避策は次のとおりです。
split()
関数を使用して、その文字列を配列の要素に分割します。_$ awk 'BEGIN { n=split("Red Green Blue", arr); for (i=1;i<=n;++i) print arr[i] }'
Red
Green
Blue
_
これは、OPが 彼ら自身の役に立つ答え でしたことです。
要素自体に空白が含まれる場合は、データの一部ではないカスタム区切り文字、この例では_|
_を使用します。
_$ awk 'BEGIN { n=split("Red (1)|Green (2)", arr, "|"); for (i=1;i<=n;++i) print arr[i] }'
Red (1)
Green (2)
_
POSIXごとに、Awkにはnotrue多次元配列があります、インデックスが暗黙的に連結されたone-次元配列を使用した、エミュレーションのみビルトイン変数SUBSEP
の値を使用して、単一キー(インデックス;allAwk配列に注意してくださいareassociative)です。
arr[1, 2]
_は実質的に_arr[1 SUBSEP 2]
_と同じです。ここで_1 SUBSEP 2
_はキー値を作成するstring concatenationです。for (i in ...)
で個別に列挙することはできません。 _1
_のみ。SUBSEP
のデフォルト値は "INFORMATION SEPARATOR ONE"文字 です。これはめったに使用されない制御文字で、日付には表示されません。 in ASCIIおよびUTF-8は、シングルバイト_0x1f
_として表されます;必要に応じて、値を変更します。対照的に、[〜#〜] gnu [〜#〜]Awk、非標準の拡張機能として、doesはtrue多次元配列をサポートしています。
arr[1,2]
_の代わりに_arr[1][2]
_を使用する必要があります。POSIX準拠の例( TrueYの役立つ答え )と同様:
_awk 'BEGIN {
n=split("Red Green Blue", arrAux); for (i in arrAux) Colors[1,i] = arrAux[i]
n=split("Yellow Cyan Purple", arrAux); for (i in arrAux) Colors[2,i] = arrAux[i]
print Colors[1,2]
print "---"
# Enumerate all [2,*] values - see comments below.
for (i in Colors) { if (index(i, 2 SUBSEP)==1) print Colors[i] }
}'
Green
---
Yellow
Cyan
Purple
_
複合キーを使用した1次元配列での多次元配列のエミュレーションには、次のような不便な意味があることに注意してください:
補助配列auxArr
が必要です。これは、配列の特定の(疑似)次元を直接設定できないためです。
one(pseudo-)dimensionをfor (i in ...)
で列挙することはできません。allインデックスのみを列挙できます。 (擬似)次元。
for (i in Colors) { if (index(i, 2 SUBSEP)==1) print Colors[i] }
は、allキーを列挙し、最初の構成インデックスが_2
_であるキーのみを照合することにより、この問題を回避する方法を示しています。キー値は_2
_で始まり、SUBSEP
が後に続く必要があります。[〜#〜] gnu [〜#〜]Awkの例( スティーブの有用な答え 、 エド・モートンの コメントで改善):
GNU Awkの(非標準の)真の多次元配列のサポートにより、POSIX準拠のソリューションの不便さが(ほとんど)なくなります
(GNU Awkには配列初期化子もありません):
_gawk 'BEGIN {
Colors[1][""]; split("Red Green Blue", Colors[1])
Colors[2][""]; split("Yellow Cyan Purple", Colors[2])
# NOTE: Always use *separate* indices: [1][2] instead of [1,2]
print Colors[1][2]
print "---"
# Enumerate all [2][*] values
for (i in Colors[2]) print Colors[2][i]
}'
_
注意:
重要:前述のように、多次元配列の特定の要素をアドレス指定するには、常にseparateを使用しますインデックス;例:_[1][2]
_ではなく_[1,2]
_。
[1,2]
_を使用すると、標準のPOSIXで義務付けられた動作が得られ、誤ってcreate(string-concatenated )値_1 SUBSEP 2
_。split()
は、サブアレイに直接データを入力するために便利に使用できます。
ただし、前提条件として、2次元のターゲット配列を初期化する必要があります。
Colors[1][""]
_および_Colors[2][""]
_はまさにそれを行います。[""]
_は、2次元配列を作成するためのものです。後でsplit()
がそのディメンションを埋めると破棄されます。for (i in ...)
を使用した特定のディメンションの列挙がサポートされています。
for (i in Colors[2]) ...
は、便利に_Colors[2]
_のサブインデックスのみを列挙します。同様のソリューション。 SUBSEP=":"
は実際には必要ありません。デモ用に表示可能な文字に設定するだけです:
awk 'BEGIN{SUBSEP=":"
split("Red Green Blue",a); for(i in a) Colors[1,i]=a[i];
split("Yellow Cyan Purple",a); for(i in a) Colors[2,i]=a[i];
for(i in Colors) print i" => "Colors[i];}'
またはもう少し謎めいたバージョン:
awk 'BEGIN{SUBSEP=":"
split("Red Green Blue Yellow Cyan Purple",a);
for(i in a) Colors[int((i-1)/3)+1,(i-1)%3+1]=a[i];
for(i in Colors) print i" => "Colors[i];}'
出力:
1:1 => Red
1:2 => Green
1:3 => Blue
2:1 => Yellow
2:2 => Cyan
2:3 => Purple