web-dev-qa-db-ja.com

文字列で配列要素を参照し、awkで配列を初期化する

#!/usr/bin/env bash
awk '
  BEGIN {
    arr[A]=1;
    arr[B]=1;
    arr[C]=1;
    arr[E]=1;
    arr[J]=8;
    arr[Q]=10;
    print arr[J]
  }'

上記のコマンドは、arr['subscript']の最新の設定値を出力します。この場合、10の直前のarr[Q]の値であり、printの直前の値であり、8ではありません。 arr[J]の値。

また、上記のスクリプトのように、同じ値arr['A'], arr['B'], arr['C'] and arr['E']を持つ値を1に一度に1行ずつ割り当てたくありません。代わりに、添え字の配列をパラメーターの1つとして渡し、共通の値を割り当てるロジックを処理する関数への他のパラメーターとしての値。

8

配列インデックスは、整数またはawk内の引用符付き文字列です。ここでは、まだ初期化されていない変数を使用しています。したがって、それらの値は空です。

各割り当てが前の値を上書きしているため、配列に割り当てられた最新の値を取得します。 print arr[""]を使用すると、10も返されます。

代わりに、arr["A"]=1のように文字列を使用します。

最後の問題の場合:コマンドラインからawk配列を初期化する実際の機能はありませんが、BEGINブロックで「デコード」した「エンコードされた」値を渡すことができます(例)配列のキーと値を抽出します。

特別に区切られたリストを単一の文字列として渡し、それを解析して使用するインデックスと値を抽出する例:

awk -v vals="A=1:B=1:C=1:E=1:J=8:Q=10" '
    BEGIN {
        n = split(vals, v, ":")
        for (i = 1; i <= n; ++i) {
            split(v[i], a, "=")
            arr[a[1]] = a[2]
        }

        print arr["J"]
    }'

個別のキーと値を使用する:

awk -v keys="A:B:C:E:J:Q" -v vals="1:1:1:1:8:10" '
    BEGIN {
        nk = split(keys, k, ":")
        nv = split(vals, v, ":")

        if (nk != nv) exit 1

        for (i = 1; i <= nk; ++i)
            arr[k[i]] = v[i]

        print arr["J"]
    }'

これは「配列」をawkに渡すための非常に限られた方法ですが、完全に制御できる単純な値に対しては機能します。これらの例は、実際のデータにコロン(および最初の例の場合は等号)を埋め込んでいるデータでは機能しません。

このようなデータを渡すことは、データ内のバックスラッシュを特別に処理する必要があることも意味します(\nは改行になるため、2文字の文字列\nを渡すには、"\\\n"を使用する必要がありますまたは'\\n')。

関連もあります:


余談ですが、次のような「純粋なawkスクリプト」を書くことができます。

#!/usr/bin/awk -f

BEGIN { 
   # some initialisations
}

some_expression { some code }

END {
    # more here
}
16
Kusalananda