bash는 임시 변수를 생성하는 대신 문자열에 대한 간접 확장을 사용할 수 있습니까?

bash는 임시 변수를 생성하는 대신 문자열에 대한 간접 확장을 사용할 수 있습니까?

우리 모두가 읽었다고 가정하면https://www.gnu.org/software/bash/manual/html_node/Shell-Parameter-Expansion.html(구체적으로 검색해 보세요.간접 확장).

질문은 다음을 수행하는 대신 다음을 의미합니다.

alpha_date=1563980822; alpha_hash=bfc1a9ad; alpha_url=http://example.com/bfc1a9ad; alpha_path=/build/alpha; alpha_status=failure; bravo_date=1563981822; bravo_hash=f76025c5; bravo_url=http://example.com/f76025c5; bravo_path=/build/alpha2; bravo_status=success; charlie_date=1563982822; charlie_hash=289f55fd; charlie_url=http://example.com/289f55fd; charlie_path=/build/charlie; charlie_status=success

for prefix in alpha bravo charlie; do
    for suffix in date hash url path status; do
        tempvar="${prefix}_${suffix}"
        echo -n "$tempvar: ${!tempvar}"$'\t'
    done
    echo
done

이것은 작동하고 출력됩니다:

alpha_date: 1563980822      alpha_hash: bfc1a9ad      alpha_url: http://example.com/bfc1a9ad      alpha_path: /build/alpha        alpha_status: failure
bravo_date: 1563981822      bravo_hash: f76025c5      bravo_url: http://example.com/f76025c5      bravo_path: /build/alpha2       bravo_status: success
charlie_date: 1563982822    charlie_hash: 289f55fd    charlie_url: http://example.com/289f55fd    charlie_path: /build/charlie    charlie_status: success

tempvar다음과 같은 작성을 건너뛰고 싶습니다 .

for prefix in alpha bravo charlie; do
    for suffix in date hash url path status; do
        echo -n "${prefix}_${suffix} is ${!${prefix}_${suffix}}"$'\t'
    done
    echo
done

하지만 물론 bad substitutionbash에서 오류가 발생했습니다.

bash를 할 수 있는 방법이 있나요?"간접 확장""로프"에?

답변1

변수 를 설정하는 방법에는 여러 가지( read "$a$b", 등)가 있습니다.printf -v "$a$b" ...declare "$a$b"=...

값을 읽으려면, 최종 값이 숫자인 경우, 산술 확장을 사용하면 됩니다. 산술 확장은 중첩될 수 있기 때문입니다(그러나 다음도 참조하세요).쉘 산술 평가에서 정리되지 않은 데이터 사용의 보안 영향):

$ a=a b=cd acd=10
$ echo $(($a$b))
10

일반적으로 bash는 중첩 대체를 지원하지 않습니다.

물론, 장난감 예제를 어느 정도 모방할 수 있습니다.

for prefix in alpha bravo charlie; do
    for suffix in date hash url path status; do
        declare -p "${prefix}_${suffix}"
    done
done

또는 다음을 시도해 볼 수 있습니다 eval.

eval "echo \"${prefix}_${suffix} is \${${prefix}_${suffix}}\""

답변2

brace expansion빌드 변수 이름을 사용할 수 있습니다 .

for i in {alpha,bravo,charlie}_{date,hash,url,path,status}; do
  echo "$i is ${!i}"
done

답변3

ksh93반대를 사용하는 경우 다음과 같이 할 수 있습니다.

data=(
  [alpha]=(
    [date]=1563980822
    [hash]=bfc1a9ad
    [url]=http://example.com/bfc1a9ad
    [path]=/build/alpha
    [status]=failure
  )
  [bravo]=(
    [date]=1563981822
    [hash]=f76025c5
    [url]=http://example.com/f76025c5
    [path]=/build/alpha2
    [status]=success
  )
  [charlie]=(
    [date]=1563982822
    [hash]=289f55fd
    [url]=http://example.com/289f55fd
    [path]=/build/charlie
    [status]=success
  )
)
for prefix in alpha bravo charlie; do
    for suffix in date hash url path status; do
        printf '%s\n' "$prefix, $suffix, ${data[$prefix][$suffix]}"
    done
done

관련 정보