Bash 배열 값은 루프 내부의 변수처럼 작동합니다.

Bash 배열 값은 루프 내부의 변수처럼 작동합니다.

루프의 배열 이름과 같은 배열 값을 사용하여 이중 루프를 수행하려고 합니다.

array1="name1 name2"
name1="one two"
name2="red blue"

for name in $array1
do 
  for value in $name
  do
    echo "$name - $value"
  done
done

두 번째 루프에서 "$name"에 "name"을 사용해야 하는데 이것이 작동하지 않습니다.
배열 이름처럼 두 번째 루프에서 array1 값을 어떻게 사용할 수 있습니까?

답변1

이곳은 당신이 있는 곳이 아닙니다 bash.

a="foo bar"

문자열/스칼라 변수를 정의합니다. 분할+글로브 연산자를 수행하는 데(따옴표 없이) 사용됩니다. 이는 $a파일 패턴의 구분된 목록을 나타내는 문자열에만 의미가 있습니다.$IFS

에서 bash배열은 다음과 같이 정의됩니다.

a=(foo bar)

여기에서 원하는 것은 다음과 같습니다.

array1=(name1 name2)
name1=(one two)
name2=(red blue)


for name in "${array1[@]}"
do
  typeset -n nameref="$name"
  for value in "${nameref[@]}"
  do
    printf '%s\n' "$name - $value"
  done
done

typeset -n비교적 새로운 추가 사항 bash이며 상태이름 참조는 다른 변수의 이름을 담고 있는 변수로, 확장하면 실제로는 지정된 변수를 가리킨다.

답변2

for value in $name에서 로 간단히 변경하면 for value in ${!name}스크립트가 제대로 작동하게 됩니다.

array1="name1 name2"; name1="one two"; name2="red blue"

for       name  in $array1     ; do 
    for   value in ${!name}    ; do
          printf '%s - %s\n' "$name" "$value"
    done
done

그러나 호출되는 변수는 array1배열이 아니라 문자열이며 전혀 아니라는 점을 지적하는 것이 중요합니다.
배열을 사용하려면 다음을 수행하십시오.

#!/bin/bash

array1=(name1 name2)
name1=(one two)
name2=(red blue)

for       name  in "${array1[@]}"     ; do
          ref="${name}[@]"
    for   value in "${!ref}"          ; do
          printf '%s - %s\n' "$name" "$value"
    done
done

bash 2.0(1997) 이상에서 간접적으로 작동합니다. 최근 4.3에 nameref가 추가되었습니다.

답변3

Stéphane Chazelas가 지적했듯이 단어 목록은 배열과 동일하지 않습니다. 그러나 다음과 같이 간접 확장을 사용할 수 있습니다.

array1="name1 name2"
name1="one two"
name2="red blue"

for name in ${array1}
do
    for value in ${!name}
    do
        echo "$name - $value"
    done
done

이 경우 ${!name}간접 수준이 도입됩니다.

관련 정보