bash-script: Variable auf textuellem Inhalt prüfen
-
Hi,
ich habe in einer Variable folgenden Text (gekürzt) stehen:
[Tue Jul 22 07:54:11 2008] [error] [client 91.66.247.162] ...HIER NUN FEHLERMELDUNG...Mit folgendem code "schneide" ich mir die IP-Adresse raus:
echo "$ERG_D" | while read line; do set $line ZEIT=$4 IPADR=$8 IPADR=${IPADR%?} shift 13 REST=$* echo "$ZEIT $IPADR D" echo "$REST" done
Funktionier wunderbar. Nun gibt es leider die seltene Ausnahme, dass in dem Bereich wo die IP-Adresse steht, etwas anders steht (also kein IP-Adresse).
So könnte die obige Textzeile z.B. so lauten:
[Tue Jul 22 07:54:11 2008] [error] [123456789 Bla Bla] ...HIER NUN FEHLERMELDUNG...oder:
[Tue Jul 22 07:54:11 2008] [error] [Irgendein Text] ...HIER NUN FEHLERMELDUNG...
Was ich nun suche, ist eine Möglichkeit zu prüfen ob der Wert welcher in die Variable IPADR abgelegt wird, der Form einer IP-Adresse entspricht.
Leider kann ich nicht sagen, was die Ausnahmen sind, es kann ein Wort oder aber auch eine Zahl anstatt der IP-Adresse stehen.
Spielt auch keine Rolle, wenn dort keine IP-Adresse steht, soll garnix ausgegeben werden.Hat jemand eine Idee ?
Gruss,
Lalas
-
Kannst du garantieren, dass das Wort "client" im String nur dann vorkommt, wenn eine IP-Adresse drin steht?
Dann könntest grep benutzen:
if echo $line | grep "client"; then ...; else ...; fi
Sonst brauchst wahrscheinlich regular expressions um nach dem Wort "client " gefolgt von Zahl,Punkt,Zahl,Punkt,Zahl,Punkt,Zahl. Ich hab aber keine Ahnung von regex in Bash.
-
Hallo,
leider verrät mein Professor nicht, welche Ausnahmen es gibt. Aber ich werde die Lösung mal implementieren, da ich davon ausgehe das bei vorhandener IP auch immer "client" davorsteht.
Danke dafür, vielleicht kann noch jemand einen Hinweis geben wie man den Textteil "durchparsen" kann um strings prüfen zu können
Gruss,
Lalas
-
lalas schrieb:
... da ich davon ausgehe das bei vorhandener IP auch immer "client" davorsteht ...
Davon würd ich mit absoluter Sicherheit ausgehen. Schlimmer wärs, wenn der Ausdruck "client" irgendwo in der Fehlermeldung (anstelle des IP-Teils oder am Ende) steht.
Du könntest natürlich mit deiner set-Methode immer $7 == "[client " abfragen.
Ich hab online doch ein bisschen was über bash-regex gefunden:
http://tille.garrels.be/training/bash/ch04.htmlif echo $line | grep "client [0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" >/dev/null; then ...; else ...; fi
Damit solltest auf der sicheren Seite sein.
Er sucht hier nach dem Wort "client ", gefolgt von einer Ziffer zwischen 0 und 9, mindestens einmal, maximal 3mal wiederholt, dann ein Punkt, usw. Die geschweiften Klammern und Punkte müssen escaped werden.
/dev/null leitet die Ausgabe von grep nach /dev/null um, damit die Konsole nicht zugemüllt wird, interessant ist hier ja nur der exit code.
-
wenn du eine große datei hast, die alle diese log meldungen enthält, ist grep sicher eine gute lösung. willst du aber immer nur eine einzelne zeile prüfen, so könnte die verwendung der bash internen regex performanter sein, da nicht jedesmal grep aufgerufen werden muss.
if [[ "[Tue Jul 22 07:54:11 2008] [error] [client 91.66.247.162] ...HIER NUN FEHLERMELDUNG... " =~ \[[^]]*]" "\[[^]]*]" "\[[^]]*" "([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3})]" ".* ]]; then echo ${BASH_REMATCH[1]} fi
das gibt dir die ip aus. ja nachdem, wie du die () in der regex positionierst, kannst du andere teile der log emldung ausgeben.