bash 배열 배열

bash 배열 배열

중첩 루프를 작성하려고 하는데 작성 방법을 모르겠습니다. 제가 잘못된 방향을 보고 있을지도 모르지만 제가 쓰고 싶은 내용은 다음과 같습니다.

declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")

declare -a subgroups=("bar" "foo")

그런 다음 하위 그룹을 반복하고 싶습니다(이에 대해서는 나중에 자세히 설명하겠습니다).술집모래부자s가 나타납니다) 요소 수가 다를 수 있으므로 내부에서 반복합니다.

원하는 출력은 다음과 유사합니다.

group name: bar with group members: alpha bravo charlie
        working on alpha of the bar group
        working on bravo of the bar group
        working on charlie of the bar group
group name: foo with group members: delta echo foxtrot golf
        working on delta of the foo group
        working on echo of the foo group
        working on foxtrot of the foo group
        working on golf of the foo group

내가 작성한 종료 코드가 실패한 것 같습니다.술집그리고부자각 세트의 요소가 포함된 배열 및 확장입니다.

for group in "${subgroups[@]}"; do
   lst=${!group}
   echo "group name: ${group} with group members: ${!lst[@]}"
   for element in "${!lst[@]}"; do
       echo -en "\tworking on $element of the $group group\n"
   done
done

출력은 다음과 같습니다

group name: bar with group members: 0
        working on 0 of the bar group
group name: foo with group members: 0
        working on 0 of the foo group

답변1

이는 매우 일반적인 문제입니다 bash. 배열 내에서 배열을 참조하려면 를 사용하여 이름 참조를 만들어야 합니다 declare -n. 다음 이름은 -n할당된 값(뒤)에 대한 이름 참조 역할을 합니다 =. 이제 nameref 속성을 사용하여 이 변수를 처리하고 마치 배열인 것처럼 확장하고 이전과 같이 완전히 올바른 참조 배열 확장을 수행합니다.

for group in "${subgroups[@]}"; do
    declare -n lst="$group"
    echo "group name: ${group} with group members: ${lst[@]}"
    for element in "${lst[@]}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done

nameref 는 bashv4.3부터만 지원됩니다. 이전 버전 및 기타 해결 방법은 다음을 참조하세요.간접/참조 변수 할당

답변2

스크립트 작동을 위한 최소한의 변경 사항은 다음과 같습니다.

#!/bin/bash

declare -a bar=("alpha" "bravo" "charlie")
declare -a foo=("delta" "echo" "foxtrot" "golf")

declare -a groups=("bar" "foo")

for group in "${groups[@]}"; do
    lst="$group[@]"
    echo "group name: ${group} with group members: ${!lst}"
    for element in "${!lst}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done

두 가지 주요 변경 사항은 다음과 같습니다.

  • 어레이를 사용 "${!lst[@]}"하거나 액세스 하지 마십시오."${!group[@]}"요소. 이 구문은오직액세스 어레이색인.

    사용 해주세요 ${!lst}".

  • 변수 lst는 다음을 포함하도록 설정되어야 합니다.일반 항목 안에 작성해야 합니다 ${ }. 즉, lst=foo[@]첫 번째 수준에서 lst="$group[@]"필요한 경우 배열 이름도 변수 값을 통해 간접적입니다 group.

     lst="$group[@]"
    

와 동등한 구문에는 확장된 값이 namerefs없습니다 !(필요하지도 않음).
따라서 [@]제거해야 합니다.

echo "using namerefs"

for group in "${groups[@]}"; do
    declare -n lst=$group
    echo "group name: ${group} with group members: ${lst[@]}"
    for element in "${lst[@]}"; do
        echo -en "\tworking on $element of the $group group\n"
    done
done

관련 정보