2012-11-09 1 views
6

Ho una lista variabile di array associativi che voglio scorrere e recuperare le loro coppie chiave/valore.Bash scripting - Iterazione tramite nomi di variabili "variabili" per un elenco di matrici associative

I iterare attraverso un singolo array associativo elencando tutte le sue chiavi e ottenendo i valori, es.

for key in "${!queue1[@]}" do 
    echo "key : $key" 
    echo "value : ${queue1[$key]}" 
done 

La parte difficile è che i nomi degli array associativi sono variabili variabili, ad es. dato count = 5, gli array associativi saranno denominati queue1, queue2, queue3, queue4, queue5.

Sto provando a sostituire la sequenza precedente in base a un conteggio, ma finora tutte le combinazioni di parentesi ed eval non hanno prodotto molto più di errori di sostituzione errati. per esempio:

for count in {1,2,3,4,5} do 
    for key in "${!queue${count}[@]}" do 
     echo "key : $key" 
     echo "value : ${queue${count}[$key]}" 
    done 
done 

L'aiuto sarebbe molto apprezzato!

+0

Le risposte attuali sono in gran parte out-of-data nel contesto del sostegno nameVar in bash 4.3 (e più tardi). –

risposta

3

La difficoltà qui deriva dal fatto che la sintassi per l'espansione indiretta (${!nameref}) è in conflitto con la sintassi per l'estrazione di chiavi da un array associativo (${!array[@]}). Possiamo avere solo l'uno o l'altro, non entrambi.

preoccupati perché sto utilizzando eval, non riesco a vedere un modo per aggirare usarlo per estrarre le chiavi di un array associativo indirettamente riferimento:

keyref="queue${count}[@]" 
for key in $(eval echo '${!'$keyref'}'); do ... ; done 

È possibile comunque evitare eval e utilizzare l'espansione indiretta durante l'estrazione di un valore da un array data la chiave. Da notare che il suffisso [key] deve essere parte dell'espansione:

valref="queue${count}[$key]" 
echo ${!valref} 

di mettere questo nel contesto:

for count in {1..5} ; do 
    keyref="queue${count}[@]" 
    for key in $(eval echo '${!'$keyref'}'); do 
     valref="queue${count}[$key]" 
     echo "key = $key" 
     echo "value = ${!valref}" 
    done 
done 
+0

Spot on! ++ per la spiegazione informativa. Grazie! – Indecided

1

sono stato in grado di farlo funzionare con il seguente script:

for count in {1..5} ; do 
    for key in $(eval echo '${!q'$count'[@]}') ; do 
     eval echo '${q'$count"[$key]}" 
    done 
done 

Nota si rompe se un tasto qualsiasi conteneva uno spazio. Se vuoi gestire strutture dati complesse, usa un linguaggio più potente come Perl.

0

Penso che questo potrebbe funzionare (ma non testato). La chiave è di trattare l'indicizzazione come nome completo di una variabile. (Vale a dire, l'array queue5 può essere trattata come una sequenza di variabili denominate queue5[this], queue5[that], etc.)

for count in {1,2,3,4,5} do 
    assoc="queue$count[@]" 
    for key in "${!assoc}" do 
     echo "key : $key" 
     val="queue$count[$key]" 
     echo "value : ${!val}" 
    done 
done 
+0

Questo sembra scorrere i valori nella matrice (invece dei tasti nella matrice). Immagino che tu possa estrarre la chiave usando il valore con un po 'di lavoro, ma potrebbe esserci un problema con valori non univoci. – doubleDown

+0

La referenziazione indiretta funziona per accedere ai valori dell'array ma non per le chiavi. Vedi la mia risposta per i dettagli. –