¿Accediendo a la variable de índice de matriz desde el bucle de script de shell bash?

Quiero acceder a la variable de índice de la matriz mientras recorro una matriz en mi script de shell bash.

myscript.sh

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

El resultado del script anterior es:

foo bar baz bat 

El resultado que busco es:

0 1 2 3 

¿Cómo modifico mi script para lograr esto?

Comentarios

  • También tenga en cuenta que básicamente nunca quiere "${array[*]}" en lugar de "${array[@]}". El uso de * en lugar de @ más o menos lo trata como una cadena en lugar de una matriz.

Respuesta

Puede hacer esto usando Lista de claves de matriz . Desde la página de manual bash:

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

Lista de claves de matriz . Si nombre es una variable de matriz, se expande a la lista de índices de matriz (claves) asignados en nombre. Si el nombre no es una matriz, se expande a 0 si el nombre está configurado y nulo en caso contrario. Cuando se usa @ y la expansión aparece entre comillas dobles, cada tecla se expande a una palabra separada.

Para su ejemplo:

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

Esto da como resultado:

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

Tenga en cuenta que esto también funciona para índices no sucesivos:

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

Esto da como resultado:

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

Comentarios

  • Aunque esta respuesta logra el resultado deseado, la declaración printf la ofusca innecesariamente. Por ejemplo: printf "$i=(${AR[i]})\n" o echo "$i=(${ARi]})" ambos dan un poco más al mostrar cómo obtener la clave & var pero estrictamente hablando echo "$i" habría respondido al OP. El resto es " bash fu " 🙂
  • Por qué no es posible: a=(1 2);echo ${a[0]} # result: 1?

Respuesta

Además de la respuesta de jordanm, también puede hacer una C como bucle en bash:

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

Comentarios

  • Solo si no era una matriz dispersa …

Responder

puede hacer algo como esto:

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

salida:

0 1 2 3 

Comentarios

  • ¿Qué dice esto que ¿La respuesta de pfnuesel no lo dice todavía?
  • Puedo estar equivocado, pero ¿la respuesta de pfnuesel no reevalúa la longitud de la matriz en cada iteración?

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *