연결된 변수 이름 역참조

연결된 변수 이름 역참조

이렇게 할 수는 있지만 변수 문자열을 만든 다음 역참조해야 합니다. 이것을 더 간단한 문장으로 단축할 수 있는 방법이 있습니까?

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

evalbash에게 두 번째 것을 생성하라고 지시 하세요평가하다다음 진술(즉, 일반적인 평가보다 하나 더 많음) \$첫 번째 평가 후에도 남아 있으면 $다음 평가에서는 $이를 변수 이름의 시작으로 처리하여 "노란색" 등으로 확인됩니다.

이렇게 하면 임시 문자열을 만들기 위해 별도의 단계가 필요하지 않습니다(귀하의 질문의 주요 목적이라고 생각합니다).

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 호출을 사용하여 두 번째 대체 라운드를 발생 ${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}"

관련 정보