2015-04-22 4 views
6

Qualcuno sa di un modo elegante per combinare due array associativi in ​​bash proprio come si farebbe con un normale array? Ecco quello che sto parlando:Come combinare gli array associativi in ​​bash?

In bash è possibile combinare due array normali come segue:

declare -ar array1=(5 10 15) 
declare -ar array2=(20 25 30) 
declare -ar array_both=(${array1[@]} ${array2[@]}) 

for item in ${array_both[@]}; do 
    echo "Item: ${item}" 
done 

voglio fare la stessa cosa con due array associativi, ma il seguente codice non funziona:

declare -Ar array1=([5]=true [10]=true [15]=true) 
declare -Ar array2=([20]=true [25]=true [30]=true) 
declare -Ar array_both=(${array1[@]} ${array2[@]}) 

for key in ${!array_both[@]}; do 
    echo "array_both[${key}]=${array_both[${key}]}" 
done 

Si dà il seguente errore:

./associative_arrays.sh: line 3: array_both: true: must use subscript when assigning associative array

il seguente è un work-ar ound mi si avvicinò con:

declare -Ar array1=([5]=true [10]=true [15]=true) 
declare -Ar array2=([20]=true [25]=true [30]=true) 
declare -A array_both=() 

for key in ${!array1[@]}; do 
    array_both+=([${key}]=${array1[${key}]}) 
done 

for key in ${!array2[@]}; do 
    array_both+=([${key}]=${array2[${key}]}) 
done 

declare -r array_both 

for key in ${!array_both[@]}; do 
    echo "array_both[${key}]=${array_both[${key}]}" 
done 

Ma speravo che sto in realtà manca un po 'di grammatica che permetterà l'assegnazione one-liner, come mostrato nell'esempio non-lavoro.

Grazie!

+1

A uno di linea richiederebbe poter espandere un array in '[chiave] = elementi valore' per ogni chiave. Non conosco alcuna espansione del genere. Il più vicino a cui riesco a pensare è ciò che 'declare -p' ti dà (che avresti bisogno di massaggiare per usare). –

+0

Bene, ho passato un sacco di tempo a giocare con array, espansione di parametri e variabili bash. Penso che sia sicuro dire che la "soluzione alternativa" nella tua domanda è il modo più pulito per copiare un array associativo. Tuttavia, potrei trasformare la tua sceneggiatura in "one-liner" con una manciata di punti e virgola, se davvero volessi ...;) – vastlysuperiorman

risposta

2

Non ho un solo liner, ma qui c'è una "soluzione" diversa che a qualcuno potrebbe piacere usare la conversione di stringhe. Sono 4 righe, quindi sono solo 3 punti e virgola dalla risposta che volevi!

declare -Ar array1=([5]=true [10]=true [15]=true) 
declare -Ar array2=([20]=true [25]=true [30]=true) 

# convert associative arrays to string 
a1="$(declare -p array1)" 
a2="$(declare -p array2)" 

#combine the two strings trimming where necessary 
array_both_string="${a1:0:${#a1}-3} ${a2:21}" 

# create new associative array from string 
eval "declare -A array_both="${array_both_string#*=} 

# show array definition 
for key in ${!array_both[@]}; do 
    echo "array_both[${key}]=${array_both[${key}]}" 
done 
+0

Sì, è certamente un lavoro alternativo che si basa sul commento di Etan. Tuttavia, non è esattamente intuitivo osservare il codice, quindi probabilmente continuerò con la mia soluzione alternativa. –

0
#!/bin/bash 

function merge_hashes() { 
    local -n DEST_VAR=$1 
    shift 

    local -n SRC_VAR 
    local KEY 

    for SRC_VAR in [email protected]; do 
     for KEY in "${!SRC_VAR[@]}"; do 
      DEST_VAR[$KEY]="${SRC_VAR[$KEY]}" 
     done 
    done 
} 

declare -Ar array1=([5]=true [10]=true [15]=true) 
declare -Ar array2=([20]=true [25]=true [30]=true) 
declare -A array_both=() 

# And here comes the one-liner: 
merge_hashes array_both array1 array2 

declare -p array_both 
+0

Puoi fornire qualche spiegazione anche? – d4Rk