Die erste Schleife looped durch die Werte 1,2,3,4,5 (jeweils durch
Newline getrennt, Variable "line"). Die Schleifenvariable "l" der
inneren Schleife nimmt die Werte "a","b","c" an.
Die Variable "test" wird ganz am Anfang auf "0" gesetzt.
Nimmt "line" den Wert 2 oder 4 an, wird "test" auf 1 gesetzt.
Ich wuerde erwarten, dass "test" auf "1" bleibt bis zum Ende.
Aber die Ausgabe ist so:
1
Start
2
1. test=0 line=1
3
1. test=0 line=2
4
2. test=1 line=2, l=a
5
2. test=1 line=2, l=b
6
2. test=1 line=2, l=c
7
1. test=0 line=3
8
1. test=0 line=4
9
2. test=1 line=4, l=a
10
2. test=1 line=4, l=b
11
2. test=1 line=4, l=c
12
1. test=0 line=5
Nimmt "line" einen naechsten Wert an, dann wird auch "test" auf 0
gesetzt. Aber warum nur? (keine Testaufgabe, ich bin wirklich ratlos)
Die Variable "test" wird nicht auf null gesetzt. Was passiert ist, dass
eine while Schleife in einer Untershell ausgefuehrt wird. Du kannst den
Wert einer Variable eines Elternprozesses nicht in einem Kindprozess
ueberschreiben, deshalb ist "test" beim Verlassen der inneren Schleife
wieder (immer noch) auf dem alten Wert.
EDIT: vielleicht etwas verstaendlicher ausgedrueckt: in einer While
Schleife arbeitest du mit Kopien der Variablen die vorher gesetzt
wurden. Beim Verlassen einer Schleife werden diese Kopien verworfen und
das Script arbeitet mit den alten Variablen weiter.
Thomas
Danke, das Raetsel ist geloest.
Aber wie kann ich im Inneren einer Schleife mir einen Zustand "merken",
den ich am Schleifenende brauche?
Abruch kommt nicht in Frage, sie muss komplett abgearbeitet werden.
Es ginge natuerlich, den Zustand in eine temporaere Datei zu speichern,
z.B.
Da ja "test" eine eingebaute Funktion der BASH ist, empfiehlt es sich
generell, diesen Namen für eigene Zwecke NICHT zu benutzen. Benenn das
mal um, zB in "Probe". Ich versprech hier keine Wunder, aber es könnte
was nützen...
Der uebersichtlichste Ansatz waere die Umwandlung der Textzeilen in ein
Array. Das gleiche Problem. Funktioniert nicht, da wegen der Pipe eine
Subshell angelegt wird.
1
i=0;
2
arr=()
3
echo -e "1\n2\n3" | while read line; do
4
arr[$i]=$line
5
echo "$i:" ${arr[$i]}
6
i=$(($i+1))
7
done
8
echo "1.Elem:" ${arr[0]}
9
exit
10
11
Start
12
0: 1
13
1: 2
14
2: 3
15
1.Elem:
Hat jemand einen Vorschlag, um NL-separierte Daten in ein Array zu
wandeln?
Bist du dir sicher dich nicht in etwas verrannt zu haben? Jedes mal wenn
ich ein aehnliches Problem hatte konnte durch Nachdenken eine wesentlich
einfachere und elegantere Loesung gefunden werden.
Und falls das Problem wirklich kompliziert ist, dann ist die Shell
vielleicht nicht das geeignete Mittel zum Problem. sed/awk oder auch
Python koennten besser dafuer geeignet sein.
Willst du uns dein eigentliches Problem schildern, dann koennte dir
wahrscheinlich am ehesten geholfen werden.
Was ganz banales.
Ich hole vom Internet eine Textdatei.
Dann sollen von dieser Textdatei alle Zeilen auf der konsole ausgegeben
werden, die einen von mehreren Begriffen enthalten.
Diese Begriffe sind als Array vorgegeben.
Z.B.
Textdatei:
1
Muenchen
2
Berlin
3
Cuxhafen
4
Frankfurt am Main
Begriffe:
1
Nuernberg
2
Augsburg
3
Muenchen
Danach soll nur
1
Muenchen
ausgegeben werden.
Die Textdatei wie das Begriffe-Array kann Leerzeichen enthalten.
Es darf NICHT nach Leerzeichen separiert werden.
Deshalb funktioniert obiger Ansatz
1
arr=($(echo -e "1 1\n2\n3" | while read l; do echo "$l"; done ))
NICHT. Denn er macht aus der ersten Zeile "1 1" zwei Array-Elemente
EDIT:
Wenn Eintraege mehrfach vorhanden sind, soll nur eine Ausgabe erfolgen,
an der Stelle des ersten Eintrages.
So ganz einfache Loesungen wie grep fallen dann schon weg.
Ja, die Reihenfolge ist wichtig.
Ich habe jetzt an den IFS rumgebastelt und die Umwandlung in ein Array
funktioniert jetzt, auch das uebrige Programm.
Allerdings braucht das Programm zur Ausfuehrung ein paar Sekunden und
der Luefter meines Notebooks laeuft los. Das heisst richtige
Rechenleistung.
Schon interessant, wie Rechenleistungs-Intensiv der Bash-Interpreter
laeuft.