내 스크립트에 그룹 이름 목록이 포함된 배열이 있습니다. 이 목록에는 고정된 수의 요소가 없습니다.
GROUPS=(group1 group2 group3)
이 그룹 집합의 각 요소에는 알 수 없는 수의 값이 있을 수 있습니다. 이름에 변수가 포함된 배열 세트를 동적으로 생성합니다. 여기서 VARIABLE은 그룹 이름입니다.
for VARIABLE in "${GROUPS[@]}"
do
declare -a ARRAY_${VARIABLE}
done
일련의 값을 반복하고 조건이 충족되면 해당 값이 속한 배열에 새 요소로 추가하고 싶습니다.
for (( VALUES=1; VALUES<=10; VALUES++ ));
do
if the VALUE belongs to GROUPx assign it to the array for GROUPx
ARRAY_$VARIABLE+=("$VALUES")
fi
done
이는 그룹에 속하는 값을 포함하는 배열로 끝나야 합니다. 즉:
ARRAY_group1= 1 2 5 9 10
ARRAY_group2= 3 7
ARRAY_group3= 4 6 8
하지만 예상치 못한 토큰 "$VALUES" 근처에서 bash: 구문 오류가 계속 발생합니다. ARRAY라는 배열에 할당하면 완벽하게 작동하지만 동적으로 생성해야 하는 알 수 없는 개수의 배열에 스크립트의 값을 할당해야 합니다.
이름에 연결된 변수가 포함된 문자열에 값을 추가한 다음 sed를 사용하여 개별 값을 선택할 수 있지만 해당 표현식에 대한 올바른 구문도 찾을 수 없습니다.
let TEST_$VARIABLE="$TEST_$VARIABLE:$VALUES"
let TEST_$VARIABLE="${TEST_$VARIABLE}:$VALUES"
let TEST_$VARIABLE="$((TEST_$VARIABLE)):$VALUES"
let TEST_$VARIABLE="$((TEST_$VARIABLE))" ":$VALUES"
몇 가지 다른 방법을 시도했지만 모두 똑같은 문제가 있었습니다. bash는 실제로 이름에 변수를 사용하는 것을 좋아하지 않지만 동적으로 생성해야 하므로 이름에 변수를 포함해야 합니다.
몇 가지 다른 방법을 시도했지만 모든 구문 오류와 잘못된 대체 오류를 피할 수 있도록 bash에서 이름에 변수가 포함된 변수를 안정적으로 참조하는 방법을 알고 계시다면 정말 감사하겠습니다.
Tldr: bash가 ARRAY[@]를 처리하는 것과 같은 방식으로 bash가 ARRAY_$VARIABLE[@]을 처리할 수 있게 하는 몇 가지 구문이 있습니까?
답변1
이름 참조
나는 nameref가 당신이 원하는 것이라고 생각합니다.
name=foo
declare -a array_$name
declare -n target=array_$name
for x in asdf 'white space' ; do target+=("$x"); done
declare -p array_$name
산출:
declare -a array_foo=([0]="asdf" [1]="white space")
평가하다, 선언하다, 하자
또 다른 더 나쁜 방법은 이러한 값을 사용 eval
하거나 설정하는 것입니다.declare
eval
$
인용이 까다로워지므로 실수로 값의 s를 확장하고 싶지는 않을 것입니다 .
eval "array_$name+=(\"\$x\")"
declare
배열에 추가하는 것을 구현하기가 약간 어렵습니다. 할당하려는 인덱스를 알고 있다면 매우 간단합니다.
declare "array_$name[$i]=$x"
(요소 수를 얻으려면 array_$name
nameref 또는 다시 필요한 것 같습니다 eval
.)
당신은 여기와 let
약간 비슷하다고 언급했지만 declare
산술 표현식의 경우 일반적인 경우에는 적합하지 않습니다.
name=a;
let "test_$name=12+34" # sets test_a to 46
let "test_$name=foo" # reads the _value_ of variable foo!
let "test_$name=foo bar" # this is an error.
대체 데이터 구조
또는 각 값이 하나만 있을 수 있는 경우 데이터 구조를 뒤집어 각 값의 그룹 ID를 단일 배열에 저장합니다.
for (( val=1; val <= 10; val++ )); do
groupid=$(find_groupid "$val")
variables[$val]=$groupid
done
그런 다음 전체 배열을 반복하고 관심 없는 그룹을 무시합니다.
또는 값에 공백이 포함되어 있지 않으면 문자열을 내부 배열로 사용하세요. 반복하려면 다음과 같이 하십시오.
for group in "${groups[@]}"; do
for item in $group; do # no quotes here, we want wordsplitting
...
(또는 연관 배열을 사용하여 그룹 이름을 저장합니다.)