특정 접두사가 붙은 모든 변수를 나열하려고 하는데 접두사가 동적으로 결정됩니다. 예를 들어:
prefix=apple_
apple_one=a1
apple_two=a2
내가 간단히 이렇게 하면:
echo ${!apple_@}
apple_로 시작하는 변수 이름을 얻을 수 있습니다. 그러나 나는 어떤 방식으로든 변수 접두사를 사용하여 이 작업을 수행하고 싶습니다. 내가 시도한 모든 결과는 잘못된 대체 결과였습니다. 예를 들어 다음과 같은 작업은 할 수 없습니다.
echo ${!${prefix}@}
답변1
Bash는 중첩된 변수 확장을 구문 분석하지 않습니다. 원하는 대로 할 수 있습니다 eval
. 즉, 쉘 조각을 작성한 ${!apple_@}
다음 실행된 명령에서 이를 사용하십시오 eval
.
prefix=apple_
eval 'vars=(${!'"$prefix"'@})'
유효한 식별자 문자만 포함 해야 합니다 prefix
. 그렇지 않으면 조각에서 결과가 생성되지 않을 수 있습니다.
eval
일반적으로 동적으로 계산된 이름을 가진 변수를 사용해야 하지만 이 특별한 경우에는 동일한 작업을 수행하는 완전히 다른 방법이 있습니다. 바로 완성 시스템을 사용하는 것입니다. Bash의 완성 시스템은 스크립트를 통해서도 실행할 수 있습니다. 내장 함수는 compgen
한 줄에 하나의 완성을 나열합니다. 완성에 개행 문자가 포함될 수 있으면 모호하지만 여기서는 그렇지 않습니다. 와일드카드도 포함되지 않으므로 따옴표가 없는 간단한 확장 출력을 사용하여 분할할 수 있습니다. 접두사에 식별자에 유효하지 않은 문자가 포함되어 있으면 아무 것도 출력되지 않습니다.
vars=($(compgen -v "$prefix"))
답변2
당신이 사용할 수있는 env | grep '^prefix'
.
예를 들어:
$ env | grep '^LESS'
LESSBINFMT=*u.
LESS=-MMqx4ij3
LESSOPEN=| /usr/bin/lesspipe %s
LESSCLOSE=/usr/bin/lesspipe %s %s
변수 이름이 아닌 값만 필요한 경우 awk를 사용하세요.
$ env | awk -F= '/^LESS/ {print $2}'
*u.
-MMqx4ij3
| /usr/bin/lesspipe %s
/usr/bin/lesspipe %s %s
(또는 $1을 변수 이름으로 인쇄)
업데이트 날짜: 2019-05-17
나는 찬성 투표를 통해 이 답변으로 돌아왔고 분명한 개선이 있음을 깨달았습니다.
typeset -p
그보다 더 나은 점은 env
내보내기 여부에 관계없이 모든 변수를 출력한다는 것입니다. 예를 들어:
typeset -p | awk '$3 ~ /^apple_/ { print $3 }'
고정 문자열 대신 변수를 사용하려면 다음을 수행하십시오.
prefix=apple_
typeset -p | awk '$3 ~ "^"pfx { print $3 }' pfx="$prefix"
또는 awk의 ENVIRON 배열에서 사용할 수 있도록 $prefix를 내보내세요.
export prefix=apple_
typeset -p | awk '$3 ~ "^"ENVIRON["prefix"] { print $3 }'
노트:약간의 작업을 통해 다른 쉘(예: ksh 또는 zsh)과 작동하도록 만들 수 있지만 typeset -p
다른 쉘에는 다른 출력 형식이 있으므로 이를 수용하도록 awk 스크립트를 수정해야 합니다.
답변3
preset(){
eval "printf %b $(#"
set -- "${1##[0-9]*}" _\[:alnum:]
[ -z "${1##*[!$2]*}" ]|| set |
sed -ne"s/^\($1[$2]*\)=.*/"'"${\1+\1\\n}" \\/p')
"; }; #"
apple_one="a single apple"
apple_two="an apple and an
apple_three='is not actually set at all'
"
preset apple_
apple_one
apple_two