連結変数名の逆参照

連結変数名の逆参照

これは可能ですが、変数文字列を作成して逆参照する必要があります。これをより簡単な文章に短縮する方法はありますか?

#!/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

evalbashに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 置換を発生させ、次に$fruitbefore呼び出しを使用して2番目の代替ラウンドを発生${fruit_color}させます。evalecho

答え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}"

関連情報