On Mon, 11 Aug 2003 at 22:20 (+0200), Thomas Moritz wrote:
Hallo zusammen, ich habe folgende Struktur am Laufen:
#!/bin/bash
zaehler=0
egrep -a -A1 ´(...egal...)´ "$myfile" | while read line do ... if [ ... ] then zaehler=`expr $zaehler + 1` ... fi if then ... fi ... ... done
exit
Solange ich $zaehler innerhalb der while-Schleife abfrage, bekomme ich die richtigen Werte. Frage ich $zaehler nach done ab, dann erhalte ich 0. Sicher habe ich heute zu lange an der Kiste gesessen um die simple Loesung zu finden:-( Ich werde wohl erst einmal Schlafen gehen:-) Vielleicht sieht ja trotzdem inzwischen jemand den Fehler:-)
Das ist kein Fehler. Aus *man bash*, Abschnitt *Pipelines*: Each command in a pipeline is executed as a separate pro cess (i.e., in a subshell). Zuerst: Mich irritiert die Option -a im egrep - was willst Du damit erreichen? Bei einem Binary sind Zeilen ja nicht so aussagekräftig ;-) Die while-Schleife läuft also in einer Subshell, und die dort verwendeten Variablen findest Du in der aufrufenden Shell (dem Script) nicht wieder. Ich sehe 3 Varianten (alles ungetestet): 1. temp. Datei: <schnipp> export zaehler=0 egrep -a -A1 '(...egal...)' "$myfile" | while read line do ... if [ ... ] then zaehler=`expr $zaehler + 1` # Zaehler in temp. Datei, immer wieder ueberschreiben echo $zaehler >temp_datei ... fi if then ... fi ... ... done # letzten Wert aus temp. Datei holen zaehler=`cat temp_datei` exit <schnapp> 2. Kommandosubstition: <schnipp> export zaehler=0 zaehler=`egrep -a -A1 '(...egal...)' "$myfile" | while read line do ... if [ ... ] then zaehler=\`expr $zaehler + 1\` # Zaehler ausgeben echo $zaehler ... fi if then ... fi ... ... # letzten ausgegebenen Wert behalten done | tail -1` exit <schnapp> Die 2. Variante kommt ohne temp. Dateien aus, hat aber den Nachteil, dass innerhalb der Schleife ein echo auf stdout passiert - wenn Du noch was anderes ausgeben willst, geht das nicht so (man könnte auf stderr ausweichen mit den restlichen Ausgaben). 3. Unter Umständen kannst Du auf die Pipe verzichten: <schnipp> zaehler=0 # alten Feldtrenner merken OFS=$IFS # neuer Feldtrenner: nur Newline IFS=' ' for line in `egrep -a -A1 '(...egal...)' "$myfile"`; do ... if [ ... ] then zaehler=`expr $zaehler + 1` ... fi if then ... fi ... ... done # Feldtrenner zuruecksetzen IFS=$OFS exit <schnapp> Damit legst Du den Input Field Separator auf Newline (Defaultmäßig gehören auch White Spaces dazu) und kannst dann die Zeilen per for-Schleife einlesen. Leerzeilen werden dann allerdings nicht gezählt, aber Dein egrep sucht ja wohl nach was Anderem ;-) Da fällt mir ein: Wenn Du Leerzeilen mitzählen willst, dann kannst Du das mit einem Trick machen: for line in `egrep -a -A1 '(...egal...)' "$myfile" | sed 's/^$/ /'`; do ... Damit ersetzt Du Leerzeilen durch eine Zeile mit einem Blank. Welche Variante bei Dir am besten passt, musst Du anhand Deines Scripts entscheiden (3. könnte z. B. schieflaufen, wenn Du innerhalb der Schleife nochmal den Original-IFS brauchst). Jan