2013-10-17 14 views
29

Ho una serie di applicazioni, inizializzato in questo modo:Come copiare una matrice in Bash?

depends=(cat ~/Depends.txt) 

Quando provo ad analizzare l'elenco e copiarlo in un nuovo array utilizzando,

for i in "${depends[@]}" 
    if [ $i #isn't installed ]; then 
     newDepends+=("$i") 
    fi 
done 

quello che succede è che solo il primo l'elemento dipende dipende da newDepends.

for i in "${newDepends[@]}" 
    echo $i 
done 

^^ Questa uscita sarebbe solo una cosa. Quindi sto cercando di capire perché il mio ciclo for sta solo spostando il primo elemento. L'intera lista è originariamente dipende, quindi non è così, ma sono tutto fuori di idee.

+0

Questo mi sembra buono. Sei sicuro che il tuo test "non installato" funzioni correttamente? – rici

+4

C'è un errore nella tua domanda? 'depends' sarà composto da 2 parole,' cat' e '~/Depends', non i contenuti di ~ ~/Depends.txt'. – chepner

risposta

1

È possibile copiare un array inserendo gli elementi del primo array nella copia specificando l'indice:

#!/bin/bash 

array=(One Two Three Go!); 
array_copy(); 

let j=0; 
for ((i=0; i<${#array[@]}; i++) 
do 
    if [[ $i -ne 1 ]]; then # change the test here to your 'isn't installed' test 
     array_copy[$j]="${array[$i]} 
     let i+=1; 
    fi 
done 

for k in "${array_copy[@]}"; do 
    echo $k 
done 

L'uscita di questo sarebbe:

One 
Three 
Go! 

Un documento utile sulla gli array di bash sono TLDP.

-3

Ho scoperto cosa non andava. Il mio se non è installato test è due cicli for che rimuovono i caratteri in eccesso dai nomi dei file e li sputa se esistono su un determinato server web. Quello che non stava facendo era rimuovere un trattino finale. Quindi, quando è stato testato online per la disponibilità, sono stati analizzati. Perché "file" esiste, ma "file-" no.

67
a=(foo bar "foo 1" "bar two") #create an array 
b=("${a[@]}")     #copy the array in another one 

for value in "${b[@]}" ; do #print the new array 
echo "$value" 
done 
+2

Va bene scrivere solo b = ($ {a [@]})? – Indicator

+4

prova ad eseguire il comando con le tue modifiche, capirai perché non è corretto scrivere senza citare ...il valore "foo 1" non verrà visualizzato come se fosse shoudl ma creerà più valore per l'array foo AND 1, bar AND due, invece di "foo 1" e "bar due" – user1088530

+0

@Indicator Avrai problemi con gli spazi! –

3

Le soluzioni presentate nelle altre risposte non funziona per array associativi, o per array con indici non contigui. Qui ci sono è una soluzione più generale:

declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!') 
temp=$(declare -p arr) 
eval "${temp/arr=/newarr=}" 

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/') 
# no output 

E un altro:

declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!') 
declare -A newarr 
for idx in "${!arr[@]}"; do 
    newarr[$idx]=${arr[$idx]} 
done 

diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/') 
# no output 
+0

La tua prima soluzione non può diventare una funzione, perché 'eval" declare -A newarr = ... "' dichiarerà in modo efficace un * local * array 'newarr' che ombreggia la variabile reale dall'ambiente padre. Potrebbe essere un'opzione per rimuovere 'declare -A' in modo che sia lasciato solo' newarr = ... ', ma ci sono problemi di escape lungo quel percorso. –

2

Partendo Bash 4.3, si può fare questo

$ alpha=(bravo charlie 'delta 3' '' foxtrot) 

$ declare -n golf=alpha 

$ echo "${golf[2]}" 
delta 3 
+11

Questa risposta non è corretta. Mentre '' 'declare -n''' è utile, crea solo un riferimento all'array originale, non lo copia, che è quello a cui si pone la domanda. – niieani

6

Il modo più semplice per copiare un array di non associativo in bash è:

arrayClone=("${oldArray[@]}")

o aggiungere elementi ad una matrice preesistente:

someArray+=("${oldArray[@]}")

newlines/spazi/IFS negli elementi saranno conservate.

Per copiare array associativi, le soluzioni di Isaac funzionano alla grande.

+0

il suo non sembra funzionare per me: '' ' $ a1 = (grande uomo di harry); $ a2 = ("$ {! A1 [@]}"); $ echo "$ {a2 [0]}"; $ echo "$ {a2 [1]}"; 1; $ '' ' –

+2

hey @FelipeAlvarez - anzi il'! 'Era superfluo, ho corretto la mia risposta – niieani

Problemi correlati