同様の配列からエントリを読み取り、スペースを含む文字列をbash配列に格納する

同様の配列からエントリを読み取り、スペースを含む文字列をbash配列に格納する

各エントリにスペースが含まれる Bash 配列を設定する方法について説明した記事をいくつか読みました。これでうまくいったと思います。

私がする必要があるのは、これをループで実行し、各反復ですべての配列の内容をより大きな配列に設定することです。

そこで、別のスクリプトから取得した配列のエントリを反復処理する外側のループを用意しました。ループの各反復処理で、数行の出力を生成するコマンド ラインを実行し、各行を配列エントリにしたいと考えています。これらの配列エントリをすべて「要約」配列に追加する必要があります。この配列の内容を単に「別の配列に追加する」方法がわからないため、小さい方の配列を反復処理する必要があると思います。これまでのところ、これで必要な処理は完了しています。ただし、大きい方の配列への追加は正しく機能していないようです。大きい方の配列に追加して大きい方の配列の長さを確認すると、常に「1」になります。

スクリプトの関連部分はおおよそ次のようになります。

nslist=$(...)
pnarray=()
for ns in $nslist; do
    IFS=$'\n' nspnarray=($(...))
    echo "nspnarray.len[${#nspnarray[@]}]" # This looks fine
    for pn in ${nspnarray[@]}; do
        echo "pn[$pn]" # This looks fine
        IFS=$'\n' pnarray+=$pn # Something wrong with this?
        echo "pnarray.len[${#pnarray[@]}]" # is always 1
    done
done

これは完全なスクリプトではないので、明確に理解していただければ幸いです。「これは問題なさそうです」というコメントの付いた行は、私が望むものを出力します。私のサンプル データでは、「nspnarray」割り当てで呼び出すコマンド ラインは 5 行の出力を生成し、「nspnarray.len」印刷ステートメントは「5」を表示します。

次に、5 つのエントリをそれぞれ繰り返して、それぞれを出力します。これではまだ問題ないようです。期待どおり、スペースを含む値が出力されます。次に、それを「要約」配列に割り当てて、要約配列の長さを出力します。常に「1」が出力されます。「これで何か問題がありますか?」の行の割り当てで何か間違っていると思います。

答え1

配列を別の配列に追加するのは非常に簡単です。

$ a=(1 2 3)
$ b=(4 5 6)
$ a+=("${b[@]}")
$ typeset -p a
declare -a a=([0]="1" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")

ただし、配列を使用して比較的複雑な処理を実行する場合は、タスクに適した言語を使用する必要があります。 awkたとえばperl、 または 。またはpython。または、bash やその他のシェルを除くほぼすべての言語を使用できます。

シェルは、他のプログラムの実行 (および他のプログラムのパイプライン、stdin と stdout のリダイレクトなど) を調整して、何かを実行したりデータを処理したりするのに適しています。シェルは、他のタスクをそれ自体で行うのは得意ではありません。実際、非常に苦手です。

awkには多次元配列 (インデックス付きと連想配列の両方) があり、perl配列またはハッシュに任意の深さでネストされた他の配列やハッシュを含めることができるデータ構造もあります。他のほとんどの言語にも複雑なデータ構造があります。

そして、同様に重要なことは、シェルのような引用や単語分割の問題がないことです。

関連情報