問題
iの値を、配列インデックスであるかのように使用しています。SAMPLE1とSAMPLE2は別々の変数であり、配列ではないため、そうではありません。
さらに、呼び出すときは、「SAMPLE」という単語にiecho SAMPLE{$i}
の値を追加するだけです。このステートメントで間接参照している唯一の変数は$iです。これが、実行した結果を取得した理由です。
問題に対処する方法
これに対処する主な方法は2つあります。
- eval組み込み変数または間接変数展開を介した、補間された変数の多段階間接参照。
- 配列を反復処理するか、iを配列へのインデックスとして使用します。
evalによる間接参照
この状況で行う最も簡単なことは、evalを使用することです。
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ )); do
eval echo \$SAMPLE${i}
done
これにより、 iの値が変数の末尾に追加され、結果の行が再処理されて、補間された変数名(SAMPLE1またはSAMPLE2など)が展開されます。
間接変数による間接参照
この質問に対する受け入れられた答えは次のとおりです。
SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'
for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done
これは技術的には3ステップのプロセスです。まず、補間された変数名をvarに割り当て、次にvarに格納されている変数名を逆参照し、最後に結果を展開します。見た目は少しすっきりしていて、evalよりもこの構文に慣れている人もいますが、結果はほとんど同じです。
配列の反復
変数の補間を使用する代わりに、配列を反復処理することで、ループと展開の両方を単純化できます。例えば:
SAMPLE=('1-first.with.custom.name' '2-second.with.custom.name')
for i in "${SAMPLE[@]}"; do
echo "$i"
done
これにより、他の方法に比べて利点が追加されました。具体的には:
- 複雑なループテストを指定する必要はありません。
- $ SAMPLE[$i]構文を介して個々の配列要素にアクセスします。
- $ {#SAMPLE}変数展開を使用して、要素の総数を取得できます。
元の例の実用的な同等性
3つの方法はすべて、元の質問で示した例で機能しますが、アレイソリューションは最も全体的な柔軟性を提供します。手元にあるデータに最適なものを選択してください。