Mat*_*Mat 13 bash variable-substitution
我可以做到这一点,但它需要制作一个变量字符串,然后取消引用它。有没有办法将其缩短为更简单的语句?
#!/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
Run Code Online (Sandbox Code Playgroud)
我尝试了很多类似${!"${fruit}_COLOUR"}or\$${fruit}_COLOUR和许多其他变体的方法,但唯一有效的方法是使用字符串。
Pet*_*r.O 11
首先,您不需要$(echo $FRUITS)在for语句中使用。使用就 $FRUITS足够了。然后,您可以使用eval.
在eval简单地告诉bash中进行第二次评估下面的语句(即一个超过其正常的评价)。The\$在第一次评估后仍然存在$,然后下一次评估将其$视为变量名称的开头,解析为“Yellow”等。
这样你就不需要一个单独的步骤来制作一个临时字符串(我认为这是你问题的主要意图)。
for fruit in $FRUITS ;do
eval echo $fruit is \$${fruit}_COLOUR
done
Run Code Online (Sandbox Code Playgroud)
对于另一种方法,如Patrick在评论(上文)中提到的,您可以改为使用关联数组,其中元素的索引不需要是整数。您可以使用字符串,例如某种水果的名称。这是一个使用 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
Run Code Online (Sandbox Code Playgroud)
您可以使用 bash-builtineval来做到这一点:
#!/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
Run Code Online (Sandbox Code Playgroud)
注意反斜线美元符号。基本上,“eval”行导致bash
替换$fruit和${fruit_color},然后使用eval在调用之前进行第二轮替换echo。