awkを使用して配列の内容を印刷すると、間違った出力が表示されるのはなぜですか?

awkを使用して配列の内容を印刷すると、間違った出力が表示されるのはなぜですか?

awkファイルから行列を読み取り、bashスクリプトで宣言された行列に割り当てようとします。しかし、すべてが正しいことを確認するために行列の内容を印刷しようとすると、奇妙な結果が出ます。関数が私の行列を上書きしています。awk行列を書き換えるのではなく、行列に追加する方法について説明しますか?

これが.txtファイルです。

ここに画像の説明を入力してください。

パスワード:

#!/bin/bash
function readMatrixFromFile() {
    local file="$1"
    declare -n matrix="$2"
    local num_rows=$(awk 'NR==1 {print $3}' $1)
    local num_colums=$(awk 'NR==2 {print $3}' $1)

    for ((i=3;i<=num_rows+2;i++)) do
    for ((j=1;j<=num_colums;j++)) do

        local k=$(($i-3))
        local l=$(($j-1))

                    matrix[$k,$l]=$(awk -v row=$i -v col=$j 'NR==row {print $col}' $file)       
            done
    done

    for ((i=0;i<num_rows;i++)) do
           for ((j=0;j<num_colums;j++)) do

                   echo ${matrix[$i,$j]}
           done
           echo
    done

}

function Main() {
    declare m
    readMatrixFromFile Matrix3.txt m

}

Main

出力は次のとおりです。

ここに画像の説明を入力してください。

ベストアンサー1

matrix[$k,$l]=$(...)

この配列の割り当ては疑わしいようです。私はBashが適切な2D配列をサポートしていないと思います。みましょう:

$ M=()
$ M[0,0]=1
$ M[0,1]=2
$ M[1,0]=3
$ M[1,1]=4
$ declare -p M
declare -a M=([0]="3" [1]="4")

はい、配列には最後の行のみがあります。これは、コンマの前のすべてのエントリが実際には適用されず、算術コンテキストの戻り値に影響を与えるためです。

$ echo $(( 123, 456 ))
456

カンマは C スタイルのコンマ演算子です。両方を評価し、右の値を返します。左側に副作用が発生する可能性があります。それBashのマニュアルで言及たとえCの目的への言及だけですが。


使いたいかもしれません連想配列代わりに、キーが文字列でカンマがキー文字列によく合うためです。

$ unset M
$ declare -A M=()
$ M[0,0]=1
$ M[0,1]=2
$ M[1,0]=3
$ M[1,1]=4
$ declare -p M
declare -A M=([1,1]="4" [1,0]="3" [0,0]="1" [0,1]="2" )

namerefを介して配列を使用します。この場合、配列を使用する前に接続する必要があると思います。

function Main() {
    declare -A m
    readMatrixFromFile Matrix3.txt m
}

awkつまり、各要素を起動するよりも配列を読み取るより簡単な方法があります。

#!/bin/bash
set -f           # disable globbing
i=0
declare -A M=()
while IFS= read -r line; do
    j=0
    for x in $line ; do     # unquoted $line to get word-splitting!
        M[$i,$j]=$x
        j=$((j+1))
    done
    i=$((i+1))
done << EOF      # replace this with a redirection from the input file
1 2 
3 4  
EOF

declare -p M

おすすめ記事