Accès à la variable d'index du tableau à partir de la boucle de script shell bash?

19

Je veux accéder à la variable d'index du tableau tout en bouclant à travers un tableau dans mon script shell bash.

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

Le résultat du script ci-dessus est:

foo
bar
baz
bat

Le résultat que je recherche est:

0
1
2
3

Comment modifier mon script pour y parvenir?

Mowzer
la source
7
Notez également que vous ne voulez pratiquement jamais "${array[*]}"au lieu de "${array[@]}". Utiliser *au lieu de @plus ou moins la traite comme une chaîne au lieu d'un tableau.
jordanm

Réponses:

27

Vous pouvez le faire en utilisant la liste des clés de tableau . Depuis la bashpage de manuel:

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

Liste des clés du tableau . Si nom est une variable de tableau, se développe dans la liste des indices de tableau (clés) attribués dans nom. Si le nom n'est pas un tableau, se développe en 0si le nom est défini et null dans le cas contraire. Lorsque @est utilisé et que l'expansion apparaît entre guillemets, chaque clé se développe en un mot distinct.

Pour votre exemple:

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

Il en résulte:

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

Notez que cela fonctionne également pour les index non successifs:

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

Il en résulte:

${AR[3]}=foo
${AR[5]}=bar
${AR[7]}=bat
${AR[25]}=baz
jordanm
la source
1
Bien que cette réponse atteigne le résultat souhaité, elle est inutilement obscurcie par l'instruction printf. Par exemple: printf "$i=(${AR[i]})\n"ou les echo "$i=(${ARi]})"deux donnent un petit plus en montrant comment obtenir key & var mais à proprement parler echo "$i"aurait répondu à l'OP. Le reste est "bash fu" :)
dimmech
5

En plus de la réponse de jordanm, vous pouvez également faire une Cboucle similaire dans bash:

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

vous pouvez faire quelque chose comme ça:

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

production:

0
1
2
3
F.9876
la source
1
Qu'est-ce que cela signifie que  la réponse de pfnuesel   ne dit pas déjà?
G-Man dit `` Réintègre Monica '' le
Je peux me tromper, mais est-ce que pfnuesels répond sans réévaluer la longueur du tableau à chaque itération?
Chris