인덱스 배열에 저장된 키-값 목록이 주어지면 각 키와 값은 개별 요소입니다.
list=(
'key$1' "value 1 line 1
value 1 line 2
"
'key$2' $'another\nmulti-line\nvalue\n'
)
다음 코드는 키-값 쌍을 올바르게 반복하고 연관 배열을 생성합니다.
declare -A arr
for (( i=0; i<${#list[*]}; i+=2 )); do
arr+=( ["${list[$i]}"]="${list[$((i+1))]}" );
done
$ declare -p arr
declare -A arr='([key2]="another
multi-line
value
" [key1]="value 1 line 1
value 1 line 2
" )'
$
이것을 달성하는 더 간단하거나 더 간결한 방법이 있습니까?
대신 arr+=([key]=value)
쓸 수 arr[key]=value
있습니다. 또한 변수에 $(())
대한 $
접두사는 list[…]
.
declare -A arr
for (( i=0; i<"${#list[*]}"; i+=2 )); do
arr["${list[i]}"]="${list[i+1]}"
done
그 외에는 스크립트가 괜찮아 보입니다. 내가 유일하고 진정한 대안은 명령 문자열과 만들 생각 eval
/ declare
하나입니다. 다음 명령어는에 키-값 쌍이 하나 이상 있다고 가정합니다 list
.
declare -A "arr=($(printf '[%q]=%q ' "${list[@]}"))"
이 declare
명령은 안전해야합니다. 또한 ARG_MAX
내장 기능 만 사용 하므로 문제가 없어야합니다 . 그러나 루프는 한 단계 더 빠른 것 같습니다. 다음 벤치 마크를 참조하십시오. 실제 데이터를 사용하여 두 가지 접근 방식을 자유롭게 벤치마킹하십시오 (매우 긴 배열을 다룰 때만 가치가 있음).
randList() {
# tr is necessary since the empty string cannot be used as a key
mapfile -d '' -n "$1" list < <(tr -s \\0 < /dev/urandom)
}
testFor() { declare -A arr; for (( i=0; i<"${#list[*]}"; i+=2 )); do arr["${list[i]}"]="${list[i+1]}"; done; }
testDeclare() { declare -A "arr=($(printf '[%q]=%q ' "${list[@]}"))"; }
prettyTime() { { time "$@"; } 2>&1 | grep -Eom1 '[0-9.sm]+'; }
for size in {1,10,50}000; do
randList "$size"
echo "list size = $size"
printf %s "for loop "; prettyTime testFor
printf %s "declare command "; prettyTime testDeclare
done
내 노트북 (bash 5.0.16, intel i5 M 520)에서 다음과 같은 결과를 얻었습니다.
list size = 1000
for loop 0m0.059s
declare command 0m0.320s
list size = 10000
for loop 0m0.435s
declare command 0m2.395s
list size = 50000
for loop 0m2.540s
declare command 0m12.276s
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다