Bashで動的に配列を作成し、変数を配列名として使用します。

Bashで動的に配列を作成し、変数を配列名として使用します。

この質問は何度も要求されましたが、どの方法も効果がありませんでした。変数から配列名を取得した配列を動的にしたいと思います。それでは配列から始めましょう。

#!/bin/bash
i="aaa"
eval ${i}=("1")

明らかにする

./1.sh: line 3: syntax error near unexpected token `('
./1.sh: line 3: `eval ${i}=("1")'

次の結果:

$(eval ${i})=('1')
$(eval echo ${i})=('1')
$(eval "echo ${i}")=('1')

すべてを評価したくなく、配列名だけを評価したいと思います。可能であれば、evalを完全に使用することを避けたいと思います。

答え1

eval引数として文字列が必要です。引用符なしでは使用できず、(シェルで特別な意味を持ちます。

i=aaa
eval "$i=(1 2)"  # Use a string, $i will expand in double quotes.
echo ${aaa[1]}

declare代わりに、typeset次のものを使用することもできますeval

declare -a $i='(1 2)'

それでも括弧とスペースを引用する必要があります。

これを完全に防ぐには、eval値を1つずつ割り当てるだけです。

#! /bin/bash
name=aaa
values=(1 2)
for ((i=0; i<${#values[@]}; ++i)) ; do
    read "$name[$i]" <<< "${values[i]}"
done
echo ${aaa[1]}

答え2

を使わずに配列をロードする方法は次のとおりですeval。構文を使用せずに、( data )代わりに入力文字列と選択した区切り文字を使用します。例では、次を使用します。|

i=aaa
IFS='|' read -a "$i" <<<"1|2   with spaces"
printf '%s\n' "${aaa[@]}"

出力:

1
2   with spaces

答え3

declare動的名前と値、および変数間接参照を使用して、その名前に基づいて変数を参照できます。printf '%q'動的割り当て中に値を使用できるように、「シェルエスケープ」値を助けることができます。

#!/bin/bash
declare -a products=( phone computer )
printf 'Product: %s\n' "${products[@]}"
# Product: phone
# Product: computer
unset products

declare varName='products'
declare -a "${varName}"='( cell\ phone laptop\ computer )'
declare arrayRef="${varName}[@]"
printf 'Product: %s\n' "${!arrayRef}"
# Product: cell phone
# Product: laptop computer
unset "${varName}"

declare -a toCopy=( 'LED TV' '"Smart" car' )
declare -a "${varName}"="( $( printf '%q ' "${toCopy[@]}" ) )"
printf 'Product: %s\n' "${!arrayRef}"
# Product: LED TV
# Product: "Smart" car
unset "${varName}"

関連情報