これは可能ですが、変数文字列を作成して逆参照する必要があります。これをより簡単な文章に短縮する方法はありますか?
#!/bin/bash
FRUITS="BANANA APPLE ORANGE"
BANANA_COLOUR="Yellow"
APPLE_COLOUR="Green or Red"
ORANGE_COLOUR="Blue"
for fruit in $( echo $FRUITS ); do
fruit_colour="${fruit}_COLOUR"
echo $fruit is ${!fruit_colour}
done
${!"${fruit}_COLOUR"}
私はorや他のいくつかのバリエーションのような多くのことを試しましたが、うまくいく\$${fruit}_COLOUR
唯一の方法は文字列を使用することです。
答え1
まず、宣言$(echo $FRUITS)
でこれを使用する必要はありません。for
使用は $FRUITS
十分です。その後、ループ内の行の1つを削除できますeval
。
eval
bashに2番目のものを作成するように指示します評価する次のステートメント(つまり、一般的な評価よりも1つ多い)\$
最初の評価の後に残っている場合は、次の$
評価では$
それを変数名の先頭として扱い、「黄色」などで解決されます。
これにより、一時的な文字列を作成するために別のステップは必要ありません(あなたの質問の主な目的だと思います)。
for fruit in $FRUITS ;do
eval echo $fruit is \$${fruit}_COLOUR
done
言及された代替方法の場合パトリックコメント(上記)では、以下を使用できます。連想配列ここで、要素のインデックスは整数である必要はありません。特定の果物の名前などの文字列を使用できます。以下は、bash連想配列を使用する例です。
# This declares an associative array (It unsets it if it already exists)
declare -A colour
colour['BANANA']="Yellow"
colour["APPLE"]="Green or Red"
colour[MARTIAN ORANGE]="Blue"
for fruit in BANANA APPLE "MARTIAN ORANGE" ;do
echo "$fruit" is "${colour[$fruit]}"
done
答え2
bash組み込みコマンドを使用してeval
これを実行できます。
#!/bin/bash
FRUITS="BANANA APPLE ORANGE"
BANANA_COLOUR="Yellow"
APPLE_COLOUR="Green or Red"
ORANGE_COLOUR="Blue"
for fruit in $( echo $FRUITS );
do
fruit_colour=${fruit}_COLOUR
eval echo $fruit is \$${fruit_colour}
done
バックスラッシュドル記号を参照してください。デフォルトでは、「eval」行はbash
置換を発生させ、次に$fruit
before呼び出しを使用して2番目の代替ラウンドを発生${fruit_color}
させます。eval
echo
答え3
eval 文は必要ありません。eval
ほとんどの言語では、何かが間違っていたことを示唆しています。
foo_var=10
bar_var=12
# Build a string with your var name of choice
chosen_prefix='foo'
var_name="${chosen_prefix}_var"
# Use bang to deference it
chossen_value=${!var_name}
echo "Chossen value: ${chossen_value}"