Ich habe mehrere Einträge, die ein Ereignis in einer sehr großen Protokolldatei beschreiben, z . B. A.log . Ich möchte zwei Dinge mit den Ereigniseinträgen in der Protokolldatei tun :
- Zählen Sie die Anzahl der Vorkommen jedes solchen Eintrags. (Dies ist keine obligatorische Anforderung, wäre aber schön zu haben.)
- Extrahieren Sie die tatsächlichen Einträge in einer separaten Datei und studieren Sie sie später.
Ein typischer Ereigniseintrag sieht wie folgt aus und enthält andere Texte. Im folgenden Beispiel gibt es also zwei Ereigniseinträge , von denen der erste zwei DataChangeEntry
Nutzdaten und der zweite eine DataChangeEntry
Nutzlast enthält.
Data control raising event :DataControl@263c015d[[
#### DataChangeEvent #### on [DataControl name=PatternMatch_LegendTimeAxis, binding=.dynamicRegion1. beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxisPageDef_beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxis_xml_ps_taskflowid.dynamicRegion58. beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxisPageDef_beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxis_xml_ps_taskflowid.QueryIterator]
Filter/Collection Id : 0
Collection Level : 0
Sequence Id : 616
ViewSetId : PatternMatch.LegendTimeAxis_V1_0_SN49
==== DataChangeEntry (#1)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 11, StrAvgCallWaitTimeGreaterThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
==== DataChangeEntry (#2)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 9, AverageCallWaitingTimeGreateThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
]]
someother non useful text
spanning multiple lines
Data control raising event :DataControl@263c015d[[
#### DataChangeEvent #### on [DataControl name=PatternMatch_LegendTimeAxis, binding=.dynamicRegion1. beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxisPageDef_beam_project_PatternMatch_dashboard_LegendTimeAxis_taskflow_LegendTimeAxis_beamDashboardLegendTimeAxis_xml_ps_taskflowid.dynamicRegion58. beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxisPageDef_beam_project_PatternMatch_view_LegendTimeAxis_taskflow_LegendTimeAxis_beamVizLegendTimeAxis_xml_ps_taskflowid.QueryIterator]
Filter/Collection Id : 0
Collection Level : 0
Sequence Id : 616
ViewSetId : PatternMatch.LegendTimeAxis_V1_0_SN49
==== DataChangeEntry (#1)
ChangeType : UPDATE
KeyPath : [2014-06-26 06:15:00.0, 0]
AttributeNames : [DATAOBJECT_CREATED, COUNTX, QueryName]
AttributeValues : [2014-06-26 06:15:00.0, 11, StrAvgCallWaitTimeGreaterThanThreshold]
AttributeTypes : [java.sql.Timestamp, java.lang.Integer, java.lang.String, ]
]]
Bitte beachten Sie, dass die Anzahl der ==== DataChangeEntry
Zeilen in einem Ereigniseintrag variabel sein kann. Es kann auch vollständig fehlen, was auf eine Nutzlast leerer Ereignisse hinweist und eine Fehlerbedingung darstellt und definitiv auch diesen Fall erfassen möchte.
Da sich in diesem Fall die Ausgabe des Eintrags über mehrere Zeilen erstreckt, komme ich mit einfachem Vanille-Grep nicht weit. Deshalb suche ich kompetenten Rat.
PS:
- Lassen Sie mich meine Anforderungen genauer erläutern. Ich möchte den gesamten oben gezeigten Textblock wörtlich erfassen und optional die Anzahl der Instanzen solcher aufgetretenen Blöcke zählen. Die Option, die Anzahl der Instanzen zu zählen, ist gut, aber keine zwingende Voraussetzung.
- Wenn die Lösung des Problems awk verwendet, möchte ich die awk-Datei speichern und wiederverwenden. Erwähnen Sie daher bitte auch die Schritte zum Ausführen des Skripts. Ich kenne Regex und Grep, bin aber nicht mit Sed und / oder Awk vertraut.
quelle
Data control raising event
?Antworten:
Das würde es hoffentlich tun. Ereignisse werden in die
events
Datei aufgenommen. Und Nachrichten gehen an stdout.Speichern Sie diese Datei in myprogram.awk (zum Beispiel):
Sie können es auf verschiedene Arten aufrufen:
myprogram.awk inputfile.txt
awk -f myprogram.awk inputfile.txt
Beispielausgabe:
Sie können alle Ereignisse zusammen in der Datei überprüfen, die
events
im Arbeitsverzeichnis aufgerufen wird .quelle
awk -f findEvents.awk A.log
?Ein sehr einfacher Ansatz wäre
Dadurch wird für jeden Eintrag eine separate Datei erstellt und die Anzahl der gefundenen Einträge in der Standardausgabe gedruckt.
Erläuterung
NR
ist die aktuelle Zeilennummer inawk
.RS="]]"
setzt das Datensatztrennzeichen (was eine "Linie" definiert) auf]]
. Dies bedeutet, dass jeder Eintrag von als einzelne Zeile von behandelt wirdawk
.{print > NR".entry"}
: Hiermit wird die aktuelle Zeile (Eintrag) in eine aufgerufene Datei gedruckt[LineNumber].entry
. Also,1.entry
wird die 1.,2.entry
die zweite und so weiter enthalten.END{print NR" entries"}
: Der END-Block wird ausgeführt, nachdem die gesamte Eingabedatei verarbeitet wurde. Daher wird an diesem PunktNR
die Anzahl der verarbeiteten Einträge angegeben.Sie können dies als Alias speichern oder wie folgt in ein Skript umwandeln:
Sie würden dann das Skript (vorausgesetzt, es heißt
foo.sh
und befindet sich in Ihrem $ PATH) mit der Zieldatei als Argument ausführen :Sie können auch die Namen der Ausgabedateien anpassen.
[date].[entry number].[entry]
Verwenden Sie stattdessen Folgendes, um die Dateien aufzurufen:Das oben Gesagte setzt voraus, dass Ihre Protokolldatei ausschließlich aus "Ereignis" -Einträgen besteht. Wenn dies nicht der Fall ist und Sie andere Zeilen haben können und diese Zeilen ignoriert werden sollten, verwenden Sie stattdessen Folgendes:
Oder als Einzeiler:
quelle