2012-04-02 18 views
5

Wie kann ich ein Array in Schleife bevölkern? Ich möchte etwas in der Art tun:bash füllen ein Array in Schleife

Aber es scheint, dass ich nichts zu einem Array innerhalb von for-Schleife hinzufügen kann. Warum?

+1

Welche Version von Bash verwenden Sie? – siride

Antwort

13

Was Sie haben sollten, vorausgesetzt, Sie haben eine Version von Bash, die assoziative Arrays zu Beginn unterstützt.

Wenn ich eine wilde Vermutung nehmen kann. . . führen Sie so etwas aus:

command_that_outputs_keys \ 
    | while read data; do 
     results[$data]=1 
    done 

? Das ist — ist Ihr while Loop-Teil einer Pipeline? Wenn ja, dann ist das das Problem. Sie sehen, jeder Befehl in einer Pipeline erhält eine Kopie der Ausführungsumgebung der Shell. Die while-Schleife würde also eine Kopie der results-Matrix auffüllen, und wenn die while-Schleife abgeschlossen ist, verschwindet diese Kopie.

Edited hinzufügen: Wenn das ist das Problem, dann als glenn jackman weist in einem Kommentar, können Sie es beheben, indem process substitution statt mit:

while read data; do 
    results[$data]=1 
done < <(command_that_outputs_keys) 

auf diese Weise, obwohl command_that_outputs_keys erhalten Nur eine Kopie der Ausführungsumgebung der Shell (wie zuvor), die while Schleife wird die ursprüngliche, Hauptumgebung haben, so kann das ursprüngliche Array ändern.

+4

+1 der Weg, um die Subshell zu vermeiden ist Prozessvertretung zu verwenden: 'while ... done <<(Befehl hier)' –

+0

@Glennjackman: Brilliant, danke! Mein erster Gedanke war "Prozesssubstitution statt verwenden", aber mein zweiter Gedanke war "Oh, warte, das würde einfach durch einen Dateinamen ersetzt, und' while' würde nicht wissen, dass er die Datei als Eingabe nehmen würde ". '<<(...)' macht jetzt Sinn, dass ich davon weiß, aber ich hätte nie gedacht, dass das erlaubt war. Ich habe meine Antwort aktualisiert. Danke noch einmal! :-D – ruakh

1

Das zu funktionieren scheint:

$ cat mkt.sh 
declare -A results 

results["a"]=1 
results["b"]=2 

while read data; do 
    results[$data]=1 
done << EOF 
3 
4 
5 
EOF 

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

$ ./mkt.sh 
key : a 
value: 1 
key : b 
value: 2 
key : 3 
value: 1 
key : 4 
value: 1 
key : 5 
value: 1 
$ 

Ubuntu 11.10 hier, bash: GNU bash, Version 4.2.10 (1) -release (x86_64-pc-linux-gnu).