ich stelle gerade fest: Mit
echo "****" | while read a; do echo $a; done
wird **** zu einem 'ls *' epandiert. Wie verhindere ich das?
Ein einfaches echo "****" | read a; echo $a macht das nicht. Es wird einfach nichts ausgegeben.
Letztlich brauche ich eine Möglichkeit eine Datei, die aus einer pipe kommt, mit read einzulesen und die Zeilen mit ****..... sollen einfach ignoriert/gelöscht werden:
formail ...... | my_skript
Nun könnte ich mir ein kompliziertes Skript basteln, dass die Zeilen nicht mit while read ... einliest, sondern mit <while-Schleife> ... read a; ... done das solange macht, bis read a ein EOF meldet. Gehts nicht einfacher?
Gruss Ekkard
Ekkard Gerlach wrote:
ich stelle gerade fest: Mit
echo "****" | while read a; do echo $a; done
wird **** zu einem 'ls *' epandiert. Wie verhindere ich das?
Ein einfaches echo "****" | read a; echo $a macht das nicht. Es wird einfach nichts ausgegeben.
Letztlich brauche ich eine Möglichkeit eine Datei, die aus einer pipe kommt, mit read einzulesen und die Zeilen mit ****..... sollen einfach ignoriert/gelöscht werden:
Versuch einmal grep:
grep -v "****" <Datei> | while ....
gibt alle Zeilen, die die Zeichenkette nicht enthalten aus.
mfg
Uwe
Uwe Diederich wrote:
Ekkard Gerlach wrote:
ich stelle gerade fest: Mit echo "****" | while read a; do echo $a; done
wird **** zu einem 'ls *' epandiert. Wie verhindere ich das? Ein einfaches echo "****" | read a; echo $a macht das nicht. Es wird einfach nichts ausgegeben. Letztlich brauche ich eine Möglichkeit eine Datei, die aus einer pipe kommt, mit read einzulesen und die Zeilen mit ****..... sollen einfach ignoriert/gelöscht werden:
Versuch einmal grep:
grep -v "****" <Datei> | while ....
gibt alle Zeilen, die die Zeichenkette nicht enthalten aus.
Ich habe das mit der pipe übersehen. Also dann etwa so:
... | grep -v "****"
mfg
Uwe
* Uwe Diederich schrieb:
Versuch einmal grep:
grep -v "****" <Datei> | while ....
gibt alle Zeilen, die die Zeichenkette nicht enthalten aus.
Ich habe das mit der pipe übersehen. Also dann etwa so:
... | grep -v "****"
damit gehts, danke, habe aber die LÖsung von Torsten genommen, das doppelte Hochkomma ist die beste LÖsung, die ********.... müssen nicht gelöscht werden.
Danke! Gruss Ekkard
On 06-Mar-08, Ekkard Gerlach wrote:
- Uwe Diederich schrieb:
Versuch einmal grep:
grep -v "****" <Datei> | while ....
gibt alle Zeilen, die die Zeichenkette nicht enthalten aus.
Ich habe das mit der pipe übersehen. Also dann etwa so:
... | grep -v "****"
Letztlich brauche ich eine Möglichkeit eine Datei, die aus einer pipe kommt, mit read einzulesen und die Zeilen mit ****..... sollen einfach ignoriert/gelöscht werden:
... | grep -v '^****'
Erklärung:
° grep -v "****"
grep erhält "****", das bedeutet "beliebig viele `*', gefolgt von beliebig vielen `*'". Das passt auf beliebig viele "*" irgendwo auf der Zeile. Dabei ist grep noch "gnädig", denn eigentlich sind der erste und der dritte "*" ein Syntax-Fehler, da "*" der "beliebig viele" Operator ist, nur daß davor nichts kommt was beliebig oft wiederholt werden könnte. Nur grep sagt sich: da meinte der Mensch wohl "*" (den normalen Stern), und nimmt den einfach. Der zweite und der vierte "*" kommen dann nach einem "ich nehm mal an der meint *"-Stern, damit haben die was zum wiederholen und tun das auch. Also steht da eigentlich '****'.
Dies passt auf Zeilen wie
"ab cd efghi askjld lkasjd ********************** askldjk" "**************** aklsdaj lsakjdlaskjda" "akjsdjskad skd a *" "abc" ""
usw. Also auch auf Zeilen die gar keine Sternchen enthalten. Grund: "**" bedeutet "beliebig viele Sternchen", inklusive keine Sternchen. Also wenigstens null Sternchen, dann nochmal null Sternchen. Das paßt also auf beliebige Zeilen, da jede Zeile mindestens null Sternchen enthält.
Dies sortiert keine Zeilen aus, bringt also nichts.
° grep -v '^****'
Dies liest sich
'^****' ^~~~~~~~~______ / \ Anfang der Zeile vier normale ("literale") Sternchen
Also vier Sternchen am Zeilenanfang. Das Ganze steht in einfachen Anführungszeichen, damit die Shell nicht die "" rausnimmt bevor das Ganze an grep weitergereicht wird. (Es empfiehlt sich, alle regulären Ausdrücke in einfache Anführungszeichen zu stellen, damit die Shell da nichts dran ändert.)
Dies paßt auf Zeilen mit vier Sternchen am Zeilenanfang. (Danach können natürlich weitere Sternchen kommen.)
Dies passt auf Zeilen wie
"**** asjkldjl askjd sdkjflk ksjdklqk" "********* jdsfklj ljkslejflskjf lske"
usw.
Es passt nicht auf
"klasdjlak lkasd **** klasdjl kljasldk" "** klajsl aslkdjlasj" "ajklsdlaj " ""
und schmeisst damit nur die Zeilen raus die mit mindestens vier Sternchen anfangen.
Gruß,
Olaf Dabrunz wrote:
On 06-Mar-08, Ekkard Gerlach wrote:
- Uwe Diederich schrieb:
Versuch einmal grep:
grep -v "****" <Datei> | while ....
gibt alle Zeilen, die die Zeichenkette nicht enthalten aus.
Ich habe das mit der pipe übersehen. Also dann etwa so:
... | grep -v "****"
Letztlich brauche ich eine Möglichkeit eine Datei, die aus einer pipe kommt, mit read einzulesen und die Zeilen mit ****..... sollen einfach ignoriert/gelöscht werden:
... | grep -v '^****'
Stimmt, danke für den Hinweis. Das ist ein Fehler, der mir leider immer mal wieder durchgeht und das nicht nur bei grep ;-)
mfg
Uwe
On Fri 07 Mar 2008 04:41:29 NZDT +1300, Uwe Diederich wrote:
echo "****" | while read a; do echo $a; done
echo "****" | while read -r a; do echo "$a"; done
Im Zweifelsfall um jede Variable "" drumherumsetzen. Es ist uralte Unix-Unsitte, das nicht zu tun. Read immer mit -r, sonst gehen Dir die Schrägstriche baden (man bash).
grep -v "****" <Datei> | while ....
Ganz sicher nicht. Erst mal hast Du Regular Expressions mit Shell Globs verwechselt, weiterhin nimmt grep da ein Suchmuster, keinen literalen Ausdruck (was sich aber mit -F umschalten ließe).
Volker
On Thu 06 Mar 2008, Ekkard Gerlach wrote:
ich stelle gerade fest: Mit
echo "****" | while read a; do echo $a; done
wird **** zu einem 'ls *' epandiert. Wie verhindere ich das?
$ echo "****" | while read a; do echo "$a"; done ****
Torsten
Hallo Ekkard,
Am Don, 06 Mär 2008, Ekkard Gerlach schrieb:
ich stelle gerade fest: Mit
echo "****" | while read a; do echo $a; done
wird **** zu einem 'ls *' epandiert. Wie verhindere ich das?
Quoten! Wenn du Variablen immer quoten würdest, was man immer tun sollte, dann hättest du das Problem nicht. Und 'ls' hat da nix mit zu tun, sondern die shell expandiert beim "echo $a" die '****' zu einer Liste von Dateinamen, die es an's builtin 'echo' gibt.
$ ls a b c $ echo "****" **** $ set -x; echo **** + echo a b c a b c
Ein einfaches echo "****" | read a; echo $a macht das nicht. Es wird einfach nichts ausgegeben.
Kommt darauf an, zu was die '****' expandiert werden können.
$ a='****'; echo "$a" $a + a=**** + echo '****' a b c **** a b c
Noch Fragen?
Letztlich brauche ich eine Möglichkeit eine Datei, die aus einer pipe kommt, mit read einzulesen und die Zeilen mit ****..... sollen einfach ignoriert/gelöscht werden:
formail ...... | my_skript
formail ... | fgrep -v '****' | my_script
oder sowas (komplett mit builtins):
$ echo -e 'a\n****\nb' | while read a; do case $a in ****) continue;; *) echo "a=$a";; esac; done + echo -e 'a\n****\nb' + read a + echo a=a a=a + read a + continue + read a + echo a=b a=b + read a
Nun könnte ich mir ein kompliziertes Skript basteln, dass die Zeilen nicht mit while read ... einliest, sondern mit <while-Schleife> ... read a; ... done das solange macht, bis read a ein EOF meldet. Gehts nicht einfacher?
Siehe oben.
-dnh