해당 배열의 변수 이름을 보유하는 다른 배열 내의 여러 배열을 참조하는 스크립트를 작성하고 싶습니다.
이것은 지금까지 내 코드입니다.
#!/bin/bash
array1=('array1string1' 'array1string2')
array2=('array2string1' 'array2string2')
array_names=('array1' 'array2')
for a in ${array_names[@]}
do
for b in ${a[@]}
do
echo $b
done
done
출력에서 두 배열(외부 for 루프에서)을 모두 스캔하고 echo를 호출하는 내부 for 루프에서 해당 문자열을 인쇄하기를 원합니다. 내 현재 출력에는 다음이 표시됩니다.
array1
array2
이 문제에 대한 조언을 주시면 감사하겠습니다. 감사합니다!
답변1
배쉬 4.3 이상"이름 참조" 또는 nameref를 지원합니다(비슷한 개념 ksh93
이범위 차이가 짜증나네요):
#!/bin/bash
array1=('array1string1' 'array1string2')
array2=('array2string1' 'array2string2')
array_names=('array1' 'array2')
for a in "${array_names[@]}"; do
declare -n arr="$a"
for b in "${arr[@]}"; do
echo "$b"
done
done
변수는 arr
이름이 지정된 변수(이 경우 이름이 있는 변수)에 대한 별칭처럼 작동하는 nameref입니다.$a
nameref가 없으면 이전 버전의 Bash에서 한 가지 해결책은 다른 배열의 모든 요소를 포함하는 새 배열을 만드는 것이었습니다.
all=( "${array1[@]}" "${array2[@]}" )
array_names
... 질문의 배열 과 비슷 하지만 모든 배열의 내용을 포함하고 이를 반복합니다 "${all[@]}"
.
또한 작동 eval
하지만 생성된 코드가 정말 나빠 보입니다.
바라보다글렌 잭맨의 답변가변 간접 참조가 있는 변형(Bash 버전 2에서 현재 형식으로 도입됨)
답변2
@Kusalananda는 최신 버전의 bash에 대한 최고의 답변을 제공합니다. 이전 버전의 경우 간접 변수를 사용할 수 있습니다.
for a in ${array_names[@]}; do
tmp="${a}[@]"
for b in "${!tmp}"; do echo "$b"; done # or: printf "%s\n" "${!tmp}"
done
4항 참조https://www.gnu.org/software/bash/manual/bashref.html#Shell-Parameter-Expansion
답변3
위의 변형으로:
#!/bin/bash
array1=('array1 string1' 'array1 string2')
array2=('array2 string1' 'array2 string2')
array_names=('array1' 'array2')
for (( i=0; i<${#array_names[@]}; i++ )); do
declare -n arr="${array_names[i]}"
for (( j=0; j<${#arr[@]}; j++ )); do
echo "${arr[j]}"
done
done
인덱스로 요소에 액세스