Accedere alla variabile dell'indice dell'array dal ciclo di script della shell bash?


19

Voglio accedere alla variabile indice dell'array mentre eseguo il looping di un array nel mio script shell bash.

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

Il risultato dello script sopra è:

foo
bar
baz
bat

Il risultato che cerco è:

0
1
2
3

Come posso modificare la mia sceneggiatura per raggiungere questo obiettivo?


7
Si noti inoltre che praticamente non si desidera mai "${array[*]}"invece di "${array[@]}". L'uso *invece di @più o meno lo considera come una stringa anziché come un array.
Giordania,

Risposte:


26

È possibile farlo utilizzando Elenco di chiavi dell'array . Dalla bashpagina man:

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

Elenco di chiavi dell'array . Se name è una variabile di array, si espande all'elenco degli indici di array (chiavi) assegnati nel nome. Se il nome non è un array, si espande a 0se il nome è impostato e null altrimenti. Quando @viene utilizzato e l'espansione appare tra virgolette, ogni chiave si espande in una parola separata.

Per il tuo esempio:

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

Questo risulta in:

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

Si noti che questo funziona anche per indici non successivi:

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

Questo risulta in:

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

1
Sebbene questa risposta raggiunga il risultato desiderato, è inutilmente offuscata dall'istruzione printf. Ad esempio: printf "$i=(${AR[i]})\n"o echo "$i=(${ARi]})"entrambi danno un piccolo extra mostrando come ottenere key & var ma in senso stretto echo "$i"avrebbe risposto al PO. Il resto è "bash fu" :)
dimmech

5

Oltre alla risposta di jordanm puoi anche fare un Cciclo simile in bash:

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

0

puoi fare qualcosa del genere:

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

produzione:

0
1
2
3

1
Cosa dice questo che  la risposta di pfnuesel   non dice già?
G-Man dice "Ripristina Monica" il

Potrei sbagliarmi, ma la risposta di pfnuesels non rivaluta la lunghezza dell'array su ogni iterazione?
Chris,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.