반응형
어레이를 루프하여 인덱스와 값을 모두 인쇄
나는 다음과 같은 것을 하고 싶다.
foo=( )
foo[0]="bar"
foo[35]="baz"
for((i=0;i<${#foo[@]};i++))
do
echo "$i: ${foo[$i]}"
done
# Output:
# 0: bar
# 1:
그런 다음 for를 사용하여 루프를 통과하려고 했습니다.
foo=( )
foo[0]="bar"
foo[35]="baz"
for i in ${foo[@]}
do
echo "?: $i"
done
# Output:
# ?: bar
# ?: naz
근데 여기 지수값은 모르겠어요
난 네가 이런 걸 할 수 있다는 걸 알아.
foo=( )
foo[0]="bar"
foo[35]="baz"
declare -p foo
# Output:
# declare -a foo='([0]="bar" [35]="baz")'
다른 방법은 없나요?
어레이 키는 다음과 같이 표시됩니다."${!foo[@]}"
(참조) 그래서:
for i in "${!foo[@]}"; do
printf "%s\t%s\n" "$i" "${foo[$i]}"
done
그 말은 즉, 지표가 그 안에 있을 거라는 거죠$i
요소 자체에 액세스 할 필요가 있는 한편,${foo[$i]}
항상 반복 매개 변수를 사용할 수 있습니다.
ITER=0
for I in ${FOO[@]}
do
echo ${I} ${ITER}
ITER=$(expr $ITER + 1)
done
INDEX=0
for i in $list; do
echo ${INDEX}_$i
let INDEX=${INDEX}+1
done
어레이 덤프를 위한 간단한 한 줄 기술
공백으로 값을 하나 추가했습니다.
foo=([12]="bar" [42]="foo bar baz" [35]="baz")
사용하는 bash 어레이 또는 관련 어레이의 빠른 덤프용
다음 한 줄 명령어:
paste <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
렌더링:
12 bar
35 baz
42 foo bar baz
설명된
printf "%s\n" "${!foo[@]}"
새 줄로 구분된 모든 키가 인쇄됩니다.printf "%s\n" "${foo[@]}"
새 줄로 구분된 모든 값이 인쇄됩니다.paste <(cmd1) <(cmd2)
의 출력을 병합합니다.cmd1
그리고.cmd2
한 줄 한 줄
튜닝
이것은, 에 의해서 조정될 수 있습니다.-d
스위치:
paste -d : <(printf "%s\n" "${!foo[@]}") <(printf "%s\n" "${foo[@]}")
12:bar
35:baz
42:foo bar baz
또는 다음과 같은 경우도 있습니다.
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}")
foo[12]='bar'
foo[35]='baz'
foo[42]='foo bar baz'
어소시에이션 어레이는 동일하게 동작합니다.
declare -A bar=([foo]=snoopy [bar]=nice [baz]=cool [foo bar]='Hello world!')
paste -d = <(printf "bar[%s]\n" "${!bar[@]}") <(printf '"%s"\n' "${bar[@]}")
bar[foo bar]="Hello world!"
bar[foo]="snoopy"
bar[bar]="nice"
bar[baz]="cool"
줄 바꿈 또는 특수 문자 문제
안타깝게도 이 기능이 더 이상 작동하지 않는 조건이 하나 이상 있습니다. 변수에 newline이 포함되어 있는 경우:
foo[17]=$'There is one\nnewline'
명령어paste
는 행별로 Marge되므로 출력이 잘못됩니다.
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "'%s'\n" "${foo[@]}")
foo[12]='bar'
foo[17]='There is one
foo[35]=newline'
foo[42]='baz'
='foo bar baz'
이 작업을 위해%q
대신%s
두 번째로printf
명령어(및 휘핑 견적):
paste -d = <(printf "foo[%s]\n" "${!foo[@]}") <(printf "%q\n" "${foo[@]}")
완벽한 렌더링(및 재사용 가능!):
foo[12]=bar
foo[17]=$'There is one\nnewline'
foo[35]=baz
foo[42]=foo\ bar\ baz
부터man bash
:
%q causes printf to output the corresponding argument in a format that can be reused as shell input.
또는 다음 기능을 사용합니다.
dumpArray() {
local -n _ary=$1
local _idx
local -i _idlen=0
for _idx in "${!_ary[@]}"; do
_idlen=" ${#_idx} >_idlen ? ${#_idx} : _idlen "
done
for _idx in "${!_ary[@]}"; do
printf "%-*s: %s\n" "$_idlen" "$_idx" \
"${_ary["$_idx"]//$'\n'/$'\n\e['${_idlen}C: }"
done
}
그럼 지금:
dumpArray foo
12: bar
17: There is one
: newline
35: baz
42: foo bar baz
dumpArray bar
foo : snoopy
bar : nice
baz : cool
foo bar: Hello world!
UTF-8 형식의 출력에 대해서
UTF-8 문자열 길이에서 다음을 추가합니다.
strU8DiffLen() { local chLen=${#1} LANG=C LC_ALL=C;return $((${#1}-chLen));}
그리고나서
dumpArray() {
local -n _ary=$1
local _idx
local -i _idlen=0
for _idx in "${!_ary[@]}"; do
_idlen=" ${#_idx} >_idlen ? ${#_idx} : _idlen "
done
for _idx in "${!_ary[@]}"; do
strU8DiffLen "$_idx"
printf "%-*s: %s\n" $(($?+$_idlen)) "$_idx" \
"${_ary["$_idx"]//$'\n'/$'\n\e['${_idlen}C: }"
done
}
데모:
foo=([12]="bar" [42]="foo bar baz" [35]="baz")
declare -A bar=([foo]=snoopy [bar]=nice [baz]=cool [foo bar]='Hello world!')
foo[17]=$'There is one\nnewline'
LANG=fr.UTF-8 printf -v bar[déjà] $'%(%a %d %b\n%Y\n%T)T' -1
dumpArray bar
déjà : ven 24 déc
: 2021
: 08:36:05
foo : snoopy
bar : nice
baz : cool
foo bar: Hello world!
dumpArray foo
12: bar
17: There is one
: newline
35: baz
42: foo bar baz
bash 4에서는 다음과 같은 연관 어레이를 사용할 수 있습니다.
declare -A foo
foo[0]="bar"
foo[35]="baz"
# for Zsh, change this to: for key in "${(k)foo[@]}"
for key in "${!foo[@]}"
do
echo "key: $key, value: ${foo[$key]}"
done
# output
# $ key: 0, value bar.
# $ key: 35, value baz.
bash 3에서는 다음과 같이 동작합니다(zsh에서도 동작합니다).
map=( )
map+=("0:bar")
map+=("35:baz")
for keyvalue in "${map[@]}" ; do
key=${keyvalue%%:*}
value=${keyvalue#*:}
echo "key: $key, value $value."
done
users=("kamal" "jamal" "rahim" "karim" "sadia")
index=()
t=-1
for i in ${users[@]}; do
t=$(( t + 1 ))
if [ $t -eq 0 ]; then
for j in ${!users[@]}; do
index[$j]=$j
done
fi
echo "${index[$t]} is $i"
done
언급URL : https://stackoverflow.com/questions/6723426/looping-over-arrays-printing-both-index-and-value
반응형
'programing' 카테고리의 다른 글
STL에서의 벡터 대 리스트 (0) | 2023.04.15 |
---|---|
엔티티 프레임워크6 트랜잭션롤백 (0) | 2023.04.15 |
EPPlus를 사용하여 열 또는 셀을 읽기 전용으로 만듭니다. (0) | 2023.04.15 |
Bash에서 어떻게 고리를 벗어날 수 있을까? (0) | 2023.04.15 |
POI HSSF API를 사용하여 Excel 셀에서 날짜 값 읽기 (0) | 2023.04.15 |