从bash shell脚本循环访问数组索引变量?


19

我想在bash shell脚本中循环访问数组时访问数组索引变量。

myscript.sh
#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
for i in ${AR[*]}; do
  echo $i
done

上面脚本的结果是:

foo
bar
baz
bat

我寻求的结果是:

0
1
2
3

如何更改脚本以实现此目的?


7
另外请注意,你基本上再也不想"${array[*]}"来代替"${array[@]}"。使用*而不是@或多或少将其视为字符串而不是数组。
jordanm '16

Answers:


27

您可以使用数组键列表执行此操作。从bash手册页:

${!name[@]}
${!name[*]}

数组键列表。如果name是数组变量,则扩展到name中分配的数组索引(键)列表。如果name不是数组,则扩展到0name设置为,否则为null。当@使用和膨胀出现双引号,每个键膨胀到一个单独的字内。

例如:

#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
for i in "${!AR[@]}"; do
  printf '${AR[%s]}=%s\n' "$i" "${AR[i]}"
done

结果是:

${AR[0]}=foo
${AR[1]}=bar
${AR[2]}=baz
${AR[3]}=bat

请注意,这对于非成功索引也适用:

#!/bin/bash
AR=([3]='foo' [5]='bar' [25]='baz' [7]='bat')
for i in "${!AR[@]}"; do
  printf '${AR[%s]}=%s\n' "$i" "${AR[i]}"
done

结果是:

${AR[3]}=foo
${AR[5]}=bar
${AR[7]}=bat
${AR[25]}=baz

1
尽管此答案可以实现预期的结果,但printf语句会不必要地混淆它。例如:printf "$i=(${AR[i]})\n"echo "$i=(${ARi]})"两者都通过显示如何获取key和var来提供一些额外的信息,但严格来说,它echo "$i"会回答OP。其余的是“ bash fu” :)
dimmech

5

除了jordanm的答案,您还可以Cbash以下位置执行类似的循环:

for ((idx=0; idx<${#array[@]}; ++idx)); do
    echo "$idx" "${array[idx]}"
done

1

您可以执行以下操作:

#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
length=${#AR[@]}
for (( i = 0; i < length; i++ )); do
  echo "$i"
done

输出:

0
1
2
3

1
这是什么说  pfnuesel的答案   已经不说?
G-Man说'Resstate Monica''s

我可能会误会,但是pfnuesels是否回答不会在每次迭代时重新评估数组长度?
克里斯,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.