[GELÖST] Strings über Zeilen finden

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

[GELÖST] Strings über Zeilen finden

Beitrag von neuling » 27.04.2010 09:47:01

Hallo,
der Titel beschreibt nicht das vollständige Problem.

Ich muss eine Oracle Log-Datei in folgendem Format auswerten.
____________________________________________________________________________
Tue Apr 26 17:09:27 2010
ORA-1652: unable to extend temp segment by 1280 in tablespace...
...
Tue Apr 26 17:48:56 2010
Thread 1 advanced to log sequence 6178
Current log# 1 seq# 6178 mem# 0: +...
Current log# 1 seq# 6178 mem# 1: +...
Tue Apr 26 17:48:56 2010
SUCCESS: diskgroup ... was mounted
SUCCESS: diskgroup ... was dismounted
SUCCESS: diskgroup ...was mounted
SUCCESS: diskgroup ... was dismounted
...
Tue Apr 27 08:23:05 2010
Errors in file .....:
ORA-27300: OS system dependent operation:fork failed with status: 12
ORA-27301: OS failure message: Not enough space
ORA-27302: failure occurred at: ...
...
Tue Apr 27 09:10:15 2010
...
____________________________________________________________________________

Am Ende sollen nur die Ereignisse ausgegeben werden, welche das "Stichwort" ORA- enthalten.
Die Anzahl der Zeilen eines Ereignisses variiert.
(Mit Ereignis meine ich alle Zeilen mit ORA- und die Zeilen darüber, einschließlich des Datums darüber.)

Wie kann ich das mit einem Shell-Script umsetzen?

Danke für Eure Hilfe.
Zuletzt geändert von neuling am 31.05.2010 13:05:44, insgesamt 3-mal geändert.

Benutzeravatar
maieutike
Beiträge: 121
Registriert: 14.03.2010 14:43:16
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Leipzig
Kontaktdaten:

Re: Strings über Zeilen finden

Beitrag von maieutike » 27.04.2010 10:20:07

Code: Alles auswählen

grep ORA output.txt
Mit -B x kannst Du auch x Zeilen vor dem Treffer noch ausgeben lassen.

Schau' auch bitte in die Manpage von grep.

neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

Geht leider nicht

Beitrag von neuling » 27.04.2010 10:36:07

maieutike hat geschrieben:

Code: Alles auswählen

grep ORA output.txt
Mit -B x kannst Du auch x Zeilen vor dem Treffer noch ausgeben lassen.

Schau' auch bitte in die Manpage von grep.
Hallo,

danke für den Tipp, aber ich habe zwei Probleme damit:
  • 1. Ich vergessen, zu erwähnen, dass ich das ganze leider nicht unter Debian machen muss, sondern unter AIX :( . Dort gibt es den Parameter leider nicht.
  • 2 .Wenn es den Parameter geben würde, hätte ich das Problem, dass ich nicht weiß wie viele Zeilen zwischen dem Datum un der Fehlermeldung stehen...

Benutzeravatar
Meillo
Moderator
Beiträge: 9252
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Strings über Zeilen finden

Beitrag von Meillo » 27.04.2010 11:23:03

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[0-9]\{2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Erklärung:
- Datei umdrehen
- Bei einer Zeile mit /^ORA/ das print-Kommando anschalten
- Bei einer Zeile mit einem Datum (das ist die komplizierte RegExp) das print-Kommando abschalten
- Datei wieder umdrehen
Use ed once in a while!

neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

Fast gelöst...

Beitrag von neuling » 27.04.2010 11:47:13

Meillo hat geschrieben:

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[0-9]\{2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Erklärung:
- Datei umdrehen
- Bei einer Zeile mit /^ORA/ das print-Kommando anschalten
- Bei einer Zeile mit einem Datum (das ist die komplizierte RegExp) das print-Kommando abschalten
- Datei wieder umdrehen
Vielen Dank, der Befehl ist ja der Wahnsinn, aber ein kleines Problem gibt's noch.
Es sind noch "nicht-Fehler" Zeilen dazwischen, wegen einstelligen Tagen. z. B. Mon Mar 8 14:05:36 2010

Wie kann man das am Besten abfangen?

Benutzeravatar
Meillo
Moderator
Beiträge: 9252
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Fast gelöst...

Beitrag von Meillo » 27.04.2010 12:13:28

neuling hat geschrieben: Vielen Dank, der Befehl ist ja der Wahnsinn,
Nicht, wenn man RegExps beherrscht. ;-)
aber ein kleines Problem gibt's noch.
Es sind noch "nicht-Fehler" Zeilen dazwischen, wegen einstelligen Tagen. z. B. Mon Mar 8 14:05:36 2010

Wie kann man das am Besten abfangen?
Indem man den Ausdruck für das Datum anpasst, natürlich.

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[0-9]\{1,2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Use ed once in a while!

neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

Noch nicht ganz gelöst, sorry

Beitrag von neuling » 27.04.2010 13:07:41

Indem man den Ausdruck für das Datum anpasst, natürlich.

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[0-9]\{1,2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Tut mir leid, wenn ich nerve,(es wird Zeit mich mal mit RegExp auseinanderzusetzen), aber vielleicht kannt du mir noch mal nen Tipp geben.

Es geht leider immer noch nicht, ich denke mal es liegt an den zwei Leerzeichen nach dem Monat, die man nicht gesehen hat:
Das zusätzliche Leerzeichen ist nur bei einstelligen Tagen...
Mon Mar--8 14:05:36 2010

Ich hätte jetzt irgendwas mit ? vermutet, aber wenn ich die Lösung sehe, dann wird mir bestimmt einiges klar...

Vielen Dank

Benutzeravatar
Meillo
Moderator
Beiträge: 9252
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Noch nicht ganz gelöst, sorry

Beitrag von Meillo » 27.04.2010 13:48:22

neuling hat geschrieben:Tut mir leid, wenn ich nerve,
Kein Problem. Ich wollte mich nicht genervt anhören, denn ich bin es nicht. :-)
(es wird Zeit mich mal mit RegExp auseinanderzusetzen), aber vielleicht kannt du mir noch mal nen Tipp geben.
Klar. Gerne.
Es geht leider immer noch nicht, ich denke mal es liegt an den zwei Leerzeichen nach dem Monat, die man nicht gesehen hat:
Das zusätzliche Leerzeichen ist nur bei einstelligen Tagen...
Mon Mar--8 14:05:36 2010
Gut erkannt, das ist mir nicht aufgefallen. Ich habe die RegExp jetzt so geändert, dass statt der ersten Ziffer des Tages auch ein Leerzeichen erlaubt ist.

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[ 0-9]\{2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Die RegExp ist ein bisschen auf ihre Länge optimiert. So ist sie verständlicher:

Code: Alles auswählen

tac | sed -n  '/^ORA/,/^[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 123][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]\{4\}$/p' | tac
Use ed once in a while!

neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

Re: Noch nicht ganz gelöst, sorry

Beitrag von neuling » 27.04.2010 14:23:28

Meillo hat geschrieben: Ich wollte mich nicht genervt anhören, denn ich bin es nicht. :-)
Nein, du hast dich nicht wirklich genervt angehört, ich habe es nur in Betracht gezogen, weil ich so viel frage :)
Meillo hat geschrieben:

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[ 0-9]\{2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Die RegExp ist ein bisschen auf ihre Länge optimiert. So ist sie verständlicher:

Code: Alles auswählen

tac | sed -n  '/^ORA/,/^[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 123][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]\{4\}$/p' | tac
:THX: Danke, jetzt klappts natürlich.

Und danke für die nette Erklärung.

Hoffentlich kann ich so etwas nächstes mal selber lösen. Ich werde heute Abend gleich mal ausprobieren, alle Links aus einem HTML-Queltext herauszufiltern. :)

Benutzeravatar
Meillo
Moderator
Beiträge: 9252
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Noch nicht ganz gelöst, sorry

Beitrag von Meillo » 27.04.2010 16:50:11

neuling hat geschrieben: :THX: Danke, jetzt klappts natürlich.

Und danke für die nette Erklärung.
Schön. Gern geschehen.

Ich werde heute Abend gleich mal ausprobieren, alle Links aus einem HTML-Queltext herauszufiltern. :)
Eine immer wieder auftauchende Aufgabe. Versuch dich ruhig daran. Das Schöne an diesem Problem ist, dass man ganz einfach anfangen kann und es dann Stück für Stück verbesser kann. Irgendwann enden die Bemühungen dann in so eine RegExp die Debianurlview verwendet (siehe: man urlview).

Aber erst selbst versuchen, bevor du bei urlview nachschaust. ;-)
Use ed once in a while!

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Strings über Zeilen finden

Beitrag von chrisbra » 29.04.2010 14:44:31

Meillo hat geschrieben:

Code: Alles auswählen

tac | sed -n '/^ORA/,/^\([A-Z][a-z][a-z] \)\{2\}[0-9]\{2\} \([0-9]\{2\}:\)\{2\}[0-9]\{2\} [0-9]\{4\}$/p' | tac
Erklärung:
- Datei umdrehen
- Bei einer Zeile mit /^ORA/ das print-Kommando anschalten
- Bei einer Zeile mit einem Datum (das ist die komplizierte RegExp) das print-Kommando abschalten
- Datei wieder umdrehen
tac, schnickschack.... ;)

Code: Alles auswählen

sed -n '/^[^ ]\{3\} [^ ]\{3\} [0-9]\+ [0-9]\+:[0-9]\+:[0-9]\+ [0-9]\+/h
/^ORA-/{
x
G
p
}' ora1.log
Funktionsweise:
- Suche Datum und speichere es
- Wenn ORA gefunden wurde, gib erst das vorherige Datum aus
und dann gib den ORA Wert aus.

Grüße,
Christian
Meine Whishlist
:wq!

Benutzeravatar
Meillo
Moderator
Beiträge: 9252
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Strings über Zeilen finden

Beitrag von Meillo » 30.04.2010 09:38:21

chrisbra hat geschrieben:

Code: Alles auswählen

sed -n '/^[^ ]\{3\} [^ ]\{3\} [0-9]\+ [0-9]\+:[0-9]\+:[0-9]\+ [0-9]\+/h
/^ORA-/{
x
G
p
}' ora1.log
Funktionsweise:
- Suche Datum und speichere es
- Wenn ORA gefunden wurde, gib erst das vorherige Datum aus
und dann gib den ORA Wert aus.
Sehr schöner Ansatz. :-)

Leider ist das Resultat nicht wie gewünscht:
- Bei mehreren ORAs unter einem Datum werden alle bis auf das letzte doppelt ausgegeben.
- Soweit ich es verstanden habe, sollen all Zeilen zwischen Datum um ORA ausgegeben werden und nicht nur die ORA-Zeilen.


Hier noch ein One-Pass-Script in awk:

Code: Alles auswählen

/^[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 123][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9][0-9][0-9][0-9]$/ {
    lines="";
}

{
    lines=lines $0 "\n";
}

/^ORA-/ {
    printf("%s",lines);
    lines="";
} 
Use ed once in a while!

chrisbra
Beiträge: 122
Registriert: 19.10.2005 09:36:09
Wohnort: Sachsen-Anhalt
Kontaktdaten:

Re: Strings über Zeilen finden

Beitrag von chrisbra » 30.04.2010 10:28:59

Meillo hat geschrieben: Sehr schöner Ansatz. :-)

Leider ist das Resultat nicht wie gewünscht:
- Bei mehreren ORAs unter einem Datum werden alle bis auf das letzte doppelt ausgegeben.
Mift, da kommt mir doch der Hold-Space in den Weg. So sollte es funktionieren:

Code: Alles auswählen

sed -n -e '/^[^ ]\{3\} [^ ]\{3\} [0-9]\+ [0-9]\+:[0-9]\+:[0-9]\+ [0-9]\+/h
/^ORA-/{
x
G
s/^\n//g
p
s/^.*$// # nuke the hold space
x
}' file
Meillo hat geschrieben: - Soweit ich es verstanden habe, sollen all Zeilen zwischen Datum um ORA ausgegeben werden und nicht nur die ORA-Zeilen.
Ja, awk oder Perl wäre dann mein nächster Versuch geworden, wenn es noch komplizierte würde.
Meine Whishlist
:wq!

neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

Strings über Zeilen finden

Beitrag von neuling » 27.05.2010 14:32:11

Hallo ich bin so weit zufriden mit folgendem Audruck:

Code: Alles auswählen

tac $LOGFILE | sed -n  '/^ORA/,/^[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 123][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]\{4\}$/p' | tac
Nun sollen aber auch die "Ereignisse" ausgegeben werden, in denen der String "Potential blocker" vorkommt.

Ich könnte natürlich folgendes machen:

Code: Alles auswählen

tac $LOGFILE |sed -n  '/Potential blocker/,/^[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 123][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]\{4\}$/p' | tac
Aber besser wäre es, wenn wenn man "Potential blocker" (durch eine OR-Verknüpfung oder so) in den ursprünglichen Befehl einbauen könnte, weil dann ja auch die Chronologische Reihenfolge stimmt und alle Meldungen "zusammenhängen"...

(Leider hatte ich nicht so viel Zeit mich so intensiv mit dem Thema zu beschäftigen, dass ich das Problem ohne Hilfe lösen kann...)

Ist das einfach lösbar, oder zu kompliziert.

Benutzeravatar
Meillo
Moderator
Beiträge: 9252
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Strings über Zeilen finden

Beitrag von Meillo » 31.05.2010 09:36:08

neuling hat geschrieben: Nun sollen aber auch die "Ereignisse" ausgegeben werden, in denen der String "Potential blocker" vorkommt.

Ich könnte natürlich folgendes machen:

Code: Alles auswählen

tac $LOGFILE |sed -n  '/Potential blocker/,/^[A-Z][a-z][a-z] [A-Z][a-z][a-z] [ 123][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9] [0-9]\{4\}$/p' | tac
Aber besser wäre es, wenn wenn man "Potential blocker" (durch eine OR-Verknüpfung oder so) in den ursprünglichen Befehl einbauen könnte, weil dann ja auch die Chronologische Reihenfolge stimmt und alle Meldungen "zusammenhängen"...
Sed unterstützt (eigentlich) nur Basic RegExp, die Auswahl (|) ist aber nur in den Extended RegExp enthalten. Wenn du nicht eine GNU-Erweiterung nutzen willst die bei sed EREs aktiviert, dann solltest du awk nehmen, denn das arbeitet mit EREs.

Es sollte nicht schwierig sein das sed-Programm durch ein awk-Programm zu ersetzen. Versuche es mal. Wenn du nicht weiter kommst, dann melde dich nochmal.
Use ed once in a while!

neuling
Beiträge: 159
Registriert: 21.07.2007 22:27:56

Re: Strings über Zeilen finden

Beitrag von neuling » 31.05.2010 13:05:25

Meillo hat geschrieben:
neuling hat geschrieben: Es sollte nicht schwierig sein das sed-Programm durch ein awk-Programm zu ersetzen. Versuche es mal. Wenn du nicht weiter kommst, dann melde dich nochmal.
Danke für den Tipp. Mein Chef ist jedoch auch mit der Lösung zufrieden, es über zwei Befehle zu filtern.
Wenn ich Urlaub habe, werde ich das mit awk mal zu Hause ausprobieren.

Antworten