我可以做到这一点,但它需要创建一个变量字符串,然后取消引用它。有什么办法可以将其缩短为更简单的语句吗?
#!/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
足够了。然后,您可以使用 删除循环内的其中一行eval
。
只是eval
告诉 bash 创建第二个评估以下陈述(即比其正常评估多一项)。\$
第一次求值后仍保留为,$
然后下一次求值将其$
视为变量名称的开头,该变量名称解析为“Yellow”等。
这样您就不需要单独的步骤来制作临时字符串(我认为这是您问题的主要目的)。
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
和${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}"