35

I want to access the array index variable while looping thru an array in my bash shell script.

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

The result of the above script is:

foo
bar
baz
bat

The result I seek is:

0
1
2
3

How do I alter my script to achieve this?

1
  • 8
    Also note that you basically never want "${array[*]}" instead of "${array[@]}". Using * instead of @ more or less treats it as a string instead of an array. – jordanm Apr 23 '16 at 2:40
41

You can do this using List of array keys. From the bash man page:

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

List of array keys. If name is an array variable, expands to the list of array indices (keys) assigned in name. If name is not an array, expands to 0 if name is set and null otherwise. When @ is used and the expansion appears within double quotes, each key expands to a separate word.

For your example:

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

This results in:

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

Note that this also work for non-successive indexes:

#!/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

This results in:

${AR[3]}=foo
${AR[5]}=bar
${AR[7]}=bat
${AR[25]}=baz
3
  • 2
    Although this answer accomplishes the desired outcome, it is unnecessarily obfuscated by the printf statement. For example: printf "$i=(${AR[i]})\n" or echo "$i=(${ARi]})" both give a little extra by showing how to get key & var but strictly speaking echo "$i" would have answered the OP. The rest is "bash fu" :) – dimmech Jul 4 '19 at 14:05
  • Why is it not possible: a=(1 2);echo ${a[0]} # result: 1? – Timo Nov 26 '20 at 7:47
  • @dimmech, I disagree. I think the printf example here is really useful too. It quickly helps orient a C or C++ programmer to how to use printf in bash, when one is already familiar with printf. I'm grateful to see this here. It gives me more value from this one answer. – Gabriel Staples Feb 20 at 23:32
9

Additional to jordanm's answer you can also do a C like loop in bash:

for ((idx=0; idx<${#array[@]}; ++idx)); do
    echo "$idx" "${array[idx]}"
done
1
  • Only if it was not a sparse array... – anthony Jun 19 '20 at 11:38
0

you can do something like this:

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

output:

0
1
2
3
2
0

Show indexes and values in same time (this script worked for me)

ARRAY=( "engineer " "CEO" "doctor" "teacher" )

for i in "${!ARRAY[@]}"
do
      echo " index---------------content"
      echo " $i                  ${ARRAY[$i]}"
done
1
  • Welcome to the site, and thank you for your contribution. Please note that your answer seems to reiterate what was already stated in the accepted answer. You may want to consider expanding it so that the difference to that answer becomes more visible; otherwise it would be best paced as a comment to that answer (once you have sufficient reputation). – AdminBee Feb 19 at 8:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.