두 명령의 출력에서 연관 배열을 만듭니다.

가져온 passwd 파일을 기반으로 사용자 디렉터리를 만들려고하고 데이터를 다음으로로드하려고합니다. 연관 배열 : array [username] = directory. 필드를 별도의 배열로로드 할 수 있지만 각 필드가 모든 디렉터리와 연결되므로 연결을 올바르게 가져올 수 없습니다.

USERLIST=$(cat /usrmkr/in.out | awk -F ":" "{print $1}") DIRLIST=$(cat /usrmkr/in.out | awk -F ":" "{print $6}") declare -A USERARRAY func_StoreData() { USERARRAY[$1]="$2" return $? } for ((u=0;u<${USERLIST[@]};u++)); do func_StoreData ${USERLIST[$u]} ${DIRLIST[$u]} done for i in ${!USERARRAY[@]}; do echo "making directory for $i in ${USERARRAY[$i]}" #Do stuff done 

댓글

  • 기존 답변으로 문제가 해결되면 다음을 통해 수락하는 것이 좋습니다. 체크 표시. 감사합니다!

답변

읽기를 콜론으로 나누라고 말하면서 bash로 전체 내용을 직접 읽을 수 있습니다. :

declare -A userarray while IFS=: read -r username password uid gid gecos home shell; do userarray[$username]=$home done < /usrmkr/in.out 

답변

 eval declare -A USERARRAY=( $(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out) )  

awk 스크립트는 [key]=val 형식으로 출력을 생성합니다. bash 연관 배열의 여러 요소를 설정할 때 필요하며 키 또는 값에 공백, 탭 등이있는 경우 키와 값 (["key"]="value")을 모두 큰 따옴표로 묶습니다. .

\n를 구분자로 사용하여 awk 다른 도구를 사용하여 출력합니다 (awk는 어쨌든 다른 도구로 수행 할 수있는 대부분의 작업을 수행 할 수 있음).

명령 대체 만으로 충분합니다 .. . 그러나 IMO로 인해 bash의 버그입니다. ( ... ) 배열 정의 내의 첫 번째 비 공백 문자가 [에서 오류 메시지 must use subscript when assigning associative array 만 생성합니다.

예 USERARRAY를 설정하려는 다음 두 시도 모두 실패합니다.

 $ bash --version | head -1 GNU bash, version 4.3.46(1)-release (x86_64-pc-linux-gnu) $ declare -A USERARRAY=($(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out)) bash: USERARRAY: $(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out): must use subscript when assigning associative array $ UA=$(awk -F: "{ printf "[\"%s\"]=\"%s\"\n", $1, $6}" /usrmkr/in.out) $ declare -A USERARRAY=( $UA ) bash: USERARRAY: $UA: must use subscript when assigning associative array  

해결 방법은 내 답변 상단의 코드 예제에서와 같이 해시 배열을 선언 할 때 eval를 사용합니다. 또는

eval declare -A USERARRY=( $UA ) 

댓글

Answer

두 목록을 병합하는 대신 목록을 반환하여 단일 루프 (그리고 적절한 측정을 위해 awk에 대한 단일 호출)로 배열을 구축 할 수 있습니다. user : dir 항목 수를 변수 확장으로 분할 :

#!/bin/bash declare -A USERARRAY for u in $(awk -F: "{print $1 ":" $6}" /usrmkr/in.out) do user=${u%:*} dir=${u#*:} USERARRAY[$user]=$dir done 

Answer

zsh는 더 유용하고 더 일반적입니다 (tcl 또는 perl와 유사). 연관 배열을 전체적으로 선언하는 방법 : array=(key1 value1 key2 value2...)

typeset -A userarray IFS=$":\n\n" userarray=($(cut -d : -f 1,6 < /usrmkr/in.out)) 

\nksh93에서와 같이 IFS 공백 문자 와 같은 개행 문자의 특수 상태를 제거합니다. 그렇지 않으면 foo:\nbar:x는 “foo”, “”, “bar”, “x”대신 “foo”, “bar”, “x”로 분할됩니다.

, 구문은 ksh93 : array=([key1]=value1 [key2]=value2)에서와 동일한 어색한 구문이므로 쉽게 출력을 얻을 수 없습니다. 다른 사람들이 보여준 것처럼 한 번에 하나의 단일 요소 할당을 수행하는 루프를 사용하는 것 이외의 연관 배열로 명령을 변환합니다.

bash 연관 배열 ( ksh93 또는 zsh와는 반대로 키가 빈 문자열 (여기서는 문제가 아님)이 될 수 없다는 제한이 있습니다. 이번에 ksh93와 공유되는 또 다른 제한은 키와 값 모두 NUL 바이트를 포함 할 수 없다는 것입니다 (여기서도 문제가되지 않음).

(연관 배열 지원은 다음과 같습니다. 처음부터 ksh93 (1993), 1998 년 zsh (3.1.5-pws-3), 2009 년 bash에 추가되었습니다 ( 4.0))

댓글

  • '를 넣은 이유 \ n ' IFS에 두 번 입력 하시겠습니까?
  • @rubystallion see edit

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다