2016-09-02 2 views
2

이 질문은 bad substitution shell- trying to use variable as name of array과 유사하지만 배열과 관련이 있습니다. 나는 bash는 스크립트 매우 새로 온 사람과 내가 필요한 것은 같은 것을 할 것입니다 :이 때 나는 bad substitution 오류 그러나Bash, 값을 호출 할 때 연관 배열의 이름으로 변수를 사용하십시오.

xxxxx.txt 

: 예상 출력으로

# input 
humantocheck="human1" 

declare -A human1 
declare -A human2 

human1=(["records_file"]="xxxxx.txt") 
human2=(["records_file"]="yyyyy.txt") 

echo ${$humantocheck[records_file]} 

. 간접 참조 이렇게

+0

'humantocheck'는 배열이 아닙니다. 어떤 일이 일어나면, $ {$ {! humantocheck} [records_file]}에 변형이 될 것입니다. 그러나 나는 확신하지 못합니다 (나는 마법의 콤보를 찾지 못했습니다). ([쉘 매개 변수 확장] (https://www.gnu.org/software/bash/manual/bash.html#Shell-Parameter-Expansion)을 참조하십시오.) –

+0

@JonathanLeffler가 살펴 봅니다. 여전히 bash에 익숙하지 않으므로 모든 그리스어입니다.) – Jonathan

+0

G [r] eek 관련 매뉴얼의 다른 섹션은 [arrays] (https://www.gnu.org/software/bash/manual/bash.html#Arrays)입니다. . 하나의 가능성은'human1' 또는'human2'에서 일반적인 연관 배열'human'을 생성 한 다음 참조하는 것입니다. 불행히도, 나는 하나의 팽창에 모든 연관 배열을 할당하는 방법이 있다고 생각하지 않습니다. 내가 사용한 가장 좋은 점은 결합 배열 요소를 요소로 복사하는 루프를 사용한다는 것입니다 :'for key in "$ {! human1 [@]}"; do human [$ key] = "$ {human1 [$ key]}"; 다. 일반적으로 간접 변수 이름을 사용하면 합병증 및 재검토/재 작성이 발생합니다. –

답변

2

한가지 방법이다

ref=$humantocheck[records_file] 
echo ${!ref} 

Bash: Indirect Expansion Exploration 배시에 변수에 대한 간접적 인 액세스를위한 우수한 기준이다.

원래 코드를 최소한으로 수정하기 위해 의도 된 echo 명령은 여러 가지 방법으로 안전하지 않습니다. 안전한 대안은 다음과 같습니다.

printf '%s\n' "${!ref}" 

Why is printf better than echo?을 참조하십시오.

+1

그것은 나를 위해 작동합니다. 그것은 흥미 롭습니다 - 구현에 대한 의미를 짐작하려고합니다. 잘 했어! 장난을 막기 위해'ref = "$ humantocheck [records_file]"'을 큰 따옴표와 함께 사용하고 싶습니다. 키는 물론 변수 안에있을 수도 있습니다 :'ref = "$ humantocheck [$ key]"'. –

+0

Brilliant! 감사! 배열에 키가 몇 개 밖에 없으므로 파일 상단에'human_file = $ humantocheck [human_name]'과 같은 변수를 만들고,'$ {! human_file}'을 템플릿 변수의 일종으로 사용할 수 있습니다. 파일 전체의 다른 모든 명령! 정말 멋진. – Jonathan

+0

[ref = $ humantocheck [$ key]'가'ref = "$보다 안전하지 않으므로 [할당 확장시 단어 분리가 수행되지 않습니다] (http://mywiki.wooledge.org/WordSplitting#Notes) $ humantocheck [ $ key] "'. – pjh

3

이는 bash 4.3 기능인 namevars (ksh93에서 빌린 것임)가 해결하고자하는 시나리오와 동일합니다. Namevars는 지정이이며, 조회 만하는 것이 아니라 ${!foo} 구문보다 유연합니다.

# input 
humantocheck="human1" 

declare -A human1=(["records_file"]="xxxxx.txt") 
declare -A human2=(["records_file"]="yyyyy.txt") 

declare -n human=$humantocheck # make human an alias for, in this case, human1 
echo "${human[records_file]}" # use that alias 
unset -n human     # discard that alias 

는 연관 배열과 일반적으로 간접 확장 모두의 포괄적 인 논의 BashFAQ #6를 참조하십시오.

+0

감사합니다! 이것도 작동합니다. – Jonathan

관련 문제