配列のgawk配列の文字列をインデックスとして使用できますか?

配列のgawk配列の文字列をインデックスとして使用できますか?

このファイルを見てみましょう。

9=foo 3=bar 84=baz 30=bin 71=bon
9=goo 3=gar 84=gaz 30=gin 71=gon
9=soo 3=sar 84=saz 30=sin 71=son

この gawk 行を実行します。

gawk '
{
    split($0,arr)
    for(i=1;i<=length(arr);i++){
        eq=index(arr[i],"=")
        num=substr(arr[i],eq+1)
        val=substr(arr[i],0,eq-1)
        printf "%s=%s ", num,val
        arr2[i][num] = val
    }
    printf ORS
}
END{
    print "---\n",arr2[2][9]}
' newfile.txt

私が得ると予想されるのは、goo配列の最初のインデックスが2行目で、2番目のインデックスがシンボルの前の数字であるためです=

例:

arr2[1][3] = bar
arr2[1][71] = bon
arr[3][30] = sin

まもなく..

なぜ機能しないのか、可能なのか教えてくれる人はいますか?

gawk バージョン GNU Awk 4.1.1, API: 1.1

ありがとうございます。

ベストアンサー1

はい、可能です。しかし、スクリプトの問題は、自分がやっていると思うことをしていないということです。まず、i最初のレベル配列のインデックスとして使用します。

arr2[i][num] = val

つまり、i1から配列の長さまでの数字になり、arr2[i]同じフィールドに同じ文字列値を持つ行がある場合は、その数字を上書きします。

これで、出力に空白行が表示される理由(私の考えではそれが表示されているようですが、実際にはそうは言っていません)は、配列で誤った順序を使用しているためです。あなたは:

arr2[i][num] = val

たとえば、次のようになります。

arr2[1][soo]=9

あなたはその反対を期待しているようです。

arr2[1][9]=soo

したがって、必要なものは次のとおりです。

arr2[i][value]=num

NR競合を避けるためにデフォルトのインデックスとして使用されるように配列定義も変更すると、次の結果がnum得られます。

gawk '
{
    split($0,arr)
    for(i=1;i<=length(arr);i++){
        eq=index(arr[i],"=")
        num=substr(arr[i],eq+1)
        val=substr(arr[i],0,eq-1)
        arr2[NR][val] = num
    }
}
END{
  for(i in arr2){
    for (num in arr2[i]){
      printf "arr2[%s][%s]=%s\n", i, num, arr2[i][num]
    }
  }
}
' newfile.txt
arr2[1][3]=bar
arr2[1][9]=foo
arr2[1][30]=bin
arr2[1][71]=bon
arr2[1][84]=baz
arr2[2][3]=gar
arr2[2][9]=goo
arr2[2][30]=gin
arr2[2][71]=gon
arr2[2][84]=gaz
arr2[3][3]=sar
arr2[3][9]=soo
arr2[3][30]=sin
arr2[3][71]=son
arr2[3][84]=saz

ご覧のとおり、arr2[2][9]gooのように動作します。すべてが少し複雑すぎます。これは次のように単純化できます。

$ awk -F'[ =]' '{
                    for(i=1;i<=NF;i+=2){
                        arr2[NR][$(i)]=$(i+1);
                    }
                } END{print  arr2[2][9]}' newfile.txt 
goo

おすすめ記事