2016-09-09 3 views
1

연관 배열에 명령 출력을 채우려고합니다. 나뿐만 명령없이 작업을 수행 할 수 있습니다bash 연관 배열을 명령 출력으로 채우려면 어떻게해야합니까?

$ declare -A x=([first]=foo [second]=bar) 
$ echo "${x[first]}, ${x[second]}" 
foo, bar 

와 나는 같은 명령 출력 비 연관 배열을 채울 수 있습니다 :

$ declare y=($(echo 'foo bar')) 
$ echo "${y[0]}, ${y[1]}" 
foo, bar 

를하지만 만들 수 위의 모두 빌드 할 때 왜 내가 그 오류 메시지가 무엇입니까

$ declare -A z=($(echo '[first]=foo [second]=bar')) 
-bash: z: $(echo '[first]=foo [second]=bar'): must use subscript when assigning associative array 

과 연관을 채울 올바른 구문 것입니다 : 명령에서 연관 배열을 채 웁니다 성명, 나는 다음과 같은 오류 메시지가 명령의 출력을 가진 배열? 나는 the usual reasonseval을 사용하지 않으려 고합니다. 임시 파일을 사용하고 싶지는 않습니다. 물론 echo은 문제의 효과를 생성하는 명령의 예로 사용됩니다. 실제 명령은 더 복잡해집니다.

그냥 내가이 문제였다 인용 것처럼 그래서, 아래의 답변의 몇 가지를 기반으로, 그것은 같습니다

$ declare -A z="($(echo '[first field]="foo with space" [second]="space bar"'))" 
$ echo "${z[first field]}, ${z[second]}" 
foo with space, space bar 

답변

2

는 전통
+0

그럴 수 있습니다. 우리는'IFS ='를 추가 할 필요가 있고,'$ '...' '를 사용하거나'\ t'을 탭으로 변환 할 수는 없습니다.하지만 우리는 아마 각 배열 요소 사이에 문자형 개행 문자 또는 NUL 문자 (그리고 NUL 플래그로 읽음)를 얻습니다. 고마워! 고마워! –

+1

우리는 내부에서'$ REPLY' 변수를 사용하고 있지만 그것을 사용하는데 해를 끼치 지 않는다면'IFS ='가 필요 없다는 말을 들었습니다. (편집) – anubhava

+0

흠, newlines은 실제로 값을 분리하는 데 차이를 만들지 않습니다. 스크립트는 값이 공백으로 분리되어있을 때 작동합니다. printf는 끝에 하나의 개행 만 있으면됩니다. –

1
: 인덱스와 값

$ declare -A z="($(echo '[first]=foo [second]=bar'))" 
$ echo "${z[first]}, ${z[second]}" 
foo, bar 

와와 공간

이 작동 주어진 :

declare -A z=([first]=$(echo 'foo') [second]=$(echo 'bar')) 

내가 배쉬는 연관 배열을 볼 필요 같은데요 용 초기화 대체를하기 전에 zation list를 사용하십시오. 그래서 방법이 eval을 피하기 위해 표시되지 않습니다 :

eval을 피하기 위해 "일반적인 이유"무엇
eval "declare -A z=($(echo '[first]=foo [second]=bar'))" 

?

+4

Google [shell eval evil] (https://www.google.com/search?q=shell+eval+evil&ie=utf-8&oe=utf-8) 'eval' 관련 문제에 대한 많은 논의가 있습니다. 응답을 주셔서 감사합니다. 여전히 대안이 있기를 바랍니다. –

+0

내가 원한 임무를 인용하는 것이 필요한 것처럼 보입니다. http://stackoverflow.com/a/39418782/1745001 하단을 참조하십시오. 조금은 당혹 스럽네요. 다시 한번 감사드립니다. –

2

이것은 다소 부서지기 쉽지만, 전체 z=(...) 할당을 명령 대체의 결과로 만들 수 있습니다. 원래 시도는 적절한 따옴표와 함께 작동합니다 :

while IFS= read -r; do 
    declare -A z+="($REPLY)" 
done < <(printf '[first]=foo [second]=bar\n[third]=baz\n') 

# check output 
$> echo "${z[first]}, ${z[second]}, ${z[third]}" 
foo, bar, baz 

# or declare -p 
$> declare -p z 
declare -A z='([third]="baz" [second]="bar" [first]="foo")' 

편집 :

$> unset z 

$> declare -A z="($(echo '[first]=foo [second]=bar'))" 

$> declare -p z 
declare -A z='([second]="bar" [first]="foo")' 
루프 방식이 명령의 출력에서 ​​연관 배열을 채우는 동안 여기
declare -A "$(echo z="($(echo '[first]=foo [second]=bar'))")" 
+0

흥미 롭습니다. 나는 그걸 생각하지 않았다. 아마'echo z = ...'를 사용하고 싶지는 않지만'printf 'z = "% s"....의 변형은 강력 할 수 있습니다. 생각 해봐야 해! 감사. –

+1

올바른 결말은'''''''''''''')'''이어야합니다. 그러나 편집을 위해서는 충분하지 않습니다 :) –

+0

따옴표로 묶지 않은' , 따옴표로 묶을 필요는 없습니다. 어쨌든 해결되었는데, 다른 입력이 작업에서 작동하지 않을 수 있다고 확신 할 수 있기 때문입니다. – chepner

관련 문제