2015-04-22 19 views
6

İki dizisel diziyi, bash'da, normal bir dizideki gibi birleştirmenin zarif bir yolunu bilen var mı? İşte bahsettiğim budur:Bash dizindeki birleştirici diziler nasıl birleştirilir?

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 

İki ilişkilendirilebilir dizilerle aynı şeyi yapmak istiyorum, ama aşağıdaki kod çalışmaz: aşağıdaki gibi iki normal diziler birleştirebilirsiniz bash ise

:

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

aşağıdaki bir iş-ar:

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 

aşağıdaki hata veriyor ound ben ile geldi:

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 

Ama aslında olmayan çalışma örnekte gösterildiği gibi tek satırlık atama sağlayacak bazı dilbilgisi özlüyorum umuyordum.

Teşekkürler!

+1

bir astar, her anahtar için '[anahtar] = value' öğeleri içine bir dizi genişletmek mümkün gerektirecektir. Ben böyle bir genişleme bilmiyorum. Düşünebildiğim en yakın şey, -p'nin size bildirdiği şeydir (kullanmak için masaj yapmanız gerekir). –

+0

Peki, diziler, parametre genişletme ve bash değişkenleri ile çok fazla zaman harcadım. Sorunuzdaki "geçici çözüm" ifadesinin, ilişkilendirici bir diziyi kopyalamanın en temiz yolu olduğunu söylemenin güvenli olduğunu düşünüyorum. Yine de, eğer sen gerçekten istiyorsan, senaryoyu bir "noktalı" ile bir çift noktalı virgül haline getirebilirim ...;) – vastlysuperiorman

cevap

2

Ben de bir tek linerim yok, ama burada birisinin string convertion kullanmayı sevdiği farklı bir 'geçici çözüm' var. 4 satır, bu yüzden istediğin cevaptan sadece 3 yarı-ben oluyorum!

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

Evet, kesinlikle Etan'ın yorumunu oluşturan alternatif bir çalışma. Kodlara baktığımızda tam olarak sezgisel değil, bu yüzden muhtemelen geçici çözümümle başa çıkacağım. –

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

Ayrıca bir açıklama da verebilir misiniz? – d4Rk