안녕하세요, StackExchange 전문가 여러분!
저는 macOS용 zsh 프로젝트를 작업 중입니다. 조판을 사용하여 값을 보관할 세 개의 연관 배열과 개별 배열을 참조하는 네 번째 배열을 만들었습니다. 각 멤버 배열에서 키/값 쌍을 검색하기 위해 arrCollection을 반복할 수 있습니까? 아래 배열의 키는 내 프로덕션 스크립트와 다릅니다. 이는 단지 키 인덱스일 뿐 연관 배열에서 찾을 수 있는 더 설명적인 키가 아닙니다.
다음과 같이 매개변수 확장을 사용할 수 있을 것 같습니다.
for k in $(sort <<< "${(kvF)arrCollection}"); do
echo "$arrCollection["${(kvF)k}"]"
done
그러나 나는 완전히 옳지 않습니다. 누구든지 도와줄 수 있나요? 예상되는 출력은 개행 문자로 구분된 세 배열 모두의 모든 항목 목록입니다.
다음은 전체 스크립트 예입니다. 사용법: arrTest.sh showAll
#!/bin/zsh
key=$1
typeset -A arrOne arrTwo arrThree
typeset -A arrCollection
#Plan is to use an array of arrays so that a for loop can be used later to loop
#through each key/value pair looking for a value that matches some pattern in an if statement
#(if statement not included here). In the showAll case, how can I use parameter expansion to print all
#of the values in each array? The if statement will further constrict what is actually echoed based on its
#value.
arrOne[1]="First"
arrOne[2]="Second"
arrOne[3]="Third"
arrOne[4]="Fourth"
arrTwo[1]="Purple"
arrTwo[2]="Orange"
arrTwo[3]="Red"
arrTwo[4]="Green"
arrTwo[5]="Blue"
arrThree[1]="First"
arrThree[2]="Red"
arrThree[3]="Planet"
arrThree[4]="Sun"
arrThree[5]="Moon"
arrThree[6]="Star"
#Array of arrays
arrCollection[1]=arrOne
arrCollection[2]=arrTwo
arrCollection[3]=arrThree
#Expect a parameter
if [ -z "$key" ]
then
echo "Please enter a parameter"
else
case "$key" in
showAll)
for k in $(sort <<< "${(kvF)arrCollection}"); do
#This is the part I am having trouble with
echo "$arrCollection["${(kvF)k}"]"
done
exit 1
;;
*)
echo "Something goes here"
exit 1
;;
esac
fi
답변1
키가 1부터 시작하는 연속적인 십진수일 때 일반 배열 대신 연관 배열을 사용하는 이유가 확실하지 않지만 원하는 것을 올바르게 이해하면 다음을 수행할 수 있습니다.
for key in "${(nok@)arrCollection}"; do
print -r - "Assoc $key: $arrCollection[$key]"
printf ' "%s" => "%s"\n' "${(@kvP)arrCollection[$key]}"
done
샘플은 다음과 같은 내용을 제공해야 합니다.
Assoc 1: arrOne
"3" => "Third"
"4" => "Fourth"
"1" => "First"
"2" => "Second"
Assoc 2: arrTwo
"3" => "Red"
"4" => "Green"
"5" => "Blue"
"1" => "Purple"
"2" => "Orange"
Assoc 3: arrThree
"3" => "Planet"
"4" => "Sun"
"5" => "Moon"
"6" => "Star"
"1" => "First"
"2" => "Red"
또는 연관된 각 멤버를 키를 기준으로 숫자순으로 정렬할 수 있습니다.
for key in "${(nok@)arrCollection}"; do
print -r - "Assoc $key: $arrCollection[$key]"
for assoc_key in "${(@knoP)arrCollection[$key]}"; do
printf ' "%s" => "%s"\n' "$assoc_key" "${${(P)arrCollection[$key]}[$assoc_key]}"
done
done
그러면 다음이 제공됩니다.
Assoc 1: arrOne
"1" => "First"
"2" => "Second"
"3" => "Third"
"4" => "Fourth"
Assoc 2: arrTwo
"1" => "Purple"
"2" => "Orange"
"3" => "Red"
"4" => "Green"
"5" => "Blue"
Assoc 3: arrThree
"1" => "First"
"2" => "Red"
"3" => "Planet"
"4" => "Sun"
"5" => "Moon"
"6" => "Star"
o
위의 키는 n
(순서) 및 (번호)를 사용하여 정렬됩니다.매개변수 확장 플래그. 이러한 요소와 비교할 때 요소는 10진수 시퀀스로 구성된 부분을 제외하고 로케일 조합을 사용하여 비교됩니다. 십진수 시퀀스는 십진수 정수로 해석되어 숫자로 비교됩니다.
sort
이는 GNU 구현에서 -V
/ 옵션을 사용하여 수행하는 작업과 유사합니다 --version-sort
.
예를 들어 foo2-3
before foo10-3
및 before 에 표시되지만 양의 십진 정수( before 및 before 에도 표시됨 ) foo2-10
이외의 숫자에는 사용할 수 없습니다 .-2
-10
2.3
2.10
sort
다른 임의의 기준을 사용하여 정렬하려면 zsh에 내장된 이 작업을 수행하는 복잡한 방법이 있지만 요소에 NL 또는 NUL 문자가 포함되지 않고 비어 있지 않다는 것을 보장할 수 있다면 더 쉬울 수 있습니다.
GNU를 예로 들어보겠습니다 sort
.
for key in ${(0)"$(print -rNC1 -- ${(k)arrCollection} | sort -zg)"}
Null이 아닌 키를 숫자로 반복하지만 이번에는 다양한 숫자 표현(0x20, 1e-1, 무한대, -20, 0x3.fp5... 포함)을 지원합니다.
위의 내용은 NUL로 구분된 레코드를 사용하여 목록을 제공 sort
하고 출력을 분할하므로 키에 NUL 문자가 포함되어 있지 않은 것으로 가정됩니다. 대신 NL/LF 문자를 사용하려면 을 삭제 -N
하고 로 -z
변경하세요 .(0)
(f)
1 및 NUL 문자는 표준 비교 API에서 차단하므로 별도로 처리해야 합니다.