我想做这样的事情:
foo=( )
foo[0]="bar"
foo[35]="baz"
for((i=0;i<${#foo[@]};i++))
do
echo "$i: ${foo[$i]}"
done
# Output:
# 0: bar
# 1:
然后我尝试使用in:
循环它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")'
但是,你不能用另一种方式吗?
答案 0 :(得分:237)
您会找到包含"${!foo[@]}"
(reference)的数组键,所以:
for i in "${!foo[@]}"; do
printf "%s\t%s\n" "$i" "${foo[$i]}"
done
这意味着索引将在$i
,而元素本身必须通过${foo[$i]}
答案 1 :(得分:13)
你总是可以使用迭代参数:
ITER=0
for I in ${FOO[@]}
do
echo ${I} ${ITER}
ITER=$(expr $ITER + 1)
done
答案 2 :(得分:5)
INDEX=0
for i in $list; do
echo ${INDEX}_$i
let INDEX=${INDEX}+1
done
答案 3 :(得分:2)
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
答案 4 :(得分:2)
我在空格处添加了一个值:
foo=()
foo[12]="bar"
foo[42]="foo bar baz"
foo[35]="baz"
I,为了快速转储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"
不幸的是,至少有一种条件使其不再起作用:当变量确实包含换行符时:
foo[17]=$'There is one\nnewline'
命令paste
将逐行合并,因此输出将变为错误:
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.
答案 5 :(得分:0)
在bash 4中,您可以使用关联数组:
declare -A foo
foo[0]="bar"
foo[35]="baz"
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