2016-06-03 10 views
0

Ich möchte eine Protokolldatei analysieren und für eine IP-Adresse grepping. Log-Datei wie folgt aussieht:Grep die letzte übereinstimmende Zeile einer Textdatei, die eine gegebene Zeichenfolge enthält, und startet nicht mit einer anderen Zeichenfolge

<date> -> <IP address> 

zum Beispiel:

2016-06-02 11:46:33 +0200 -> 86.171.55.134 

So würde Ich mag die letzte Zeile auszuwählen, die eine bestimmte IP enthält, und die Zeile beginnt nicht mit dem heutigen Datum (2016 -06-02), mein erster Versuch funktioniert leider nicht:

tac logfile.txt|grep -P '^(?<!2016-06-03).*?86.171.55.134' 

auf diese Weise gelang es mir, damit es funktioniert, aber ich möchte eine allgemeinere Art und Weise arbeiten, wo ich verwenden kann, * oder. . *? anstelle von 19 Punkten, denn manchmal gibt es mehr und unbekannte Längendaten zwischen den beiden Muster:

tac logfile.txt|grep -aP -m1 '(?<!2016\-06\-03)...................86.171.55.134' 

Hier 5000 aktuelle Zeile von Protokolldaten mit spielen:

http://www.filefactory.com/file/2sdj77aqflxp/5000.txt

nur die IP-Adressen wurden gefälscht.

+0

versuchen, eine [mcve] bereitzustellen, weil dies zu wenig ist, um mit dem Spielen zu beginnen. – fedorqui

Antwort

1

^(?<!2016-06-03).*?86.171.55.134 diese regex wird nie funktionieren läßt es brechen zu verstehen:

^    # Start of line 
(?<!2016-06-03) # Negative look behind searching for 2016-06-03 

Kann es vor Start der Linie irgendetwas geben?

Vielleicht möchten Sie versuchen, es zu einem Blick zu ändern voraus:

tac logfile.txt | grep -P '^(?!2016-06-03).*?86.171.55.134' 

Oder mit sed:

tac logfile.txt | sed -n '/^2016-06-03/!{/86\.171\.55\.134/p}' 

Und wenn Sie wollen nur das erste (letzte wegen tac) Spiel:

tac logfile.txt | sed -n '/^2016-06-03/!{/86\.171\.55\.134/{p;q}}' 
+0

sed-Methode funktioniert, Grep-Methode nicht, es druckt eine Zeile, die mit dem non beginnt benötigtes Datum. – Konstantin

+0

vor der Datumszeichenkette gibt es nichts, es ist der Anfang der Zeile. – Konstantin

+0

@Konstantin Was funktioniert nicht mit dem Grep? – andlrc

0

grep ist dein kleiner Freund dafür.

tac logfile.txt | grep -w "86.171.55.134" | grep -vw "2016-06-02" | head -1 

Wird wahrscheinlich die Arbeit brauchen für Sie tun. Ich kann es nicht wirklich mit deinem Log testen. Was es tut, ist mit -v Option, die Invert-Match am heutigen Datum 2016-06-02 wird alle Einträge mit dem aktuellen Datum auszuschließen, und ich habe einen anderen Ausdruck |86.171.55.134 hinzugefügt, um die Zeile mit Ihrer IP entsprechen.

Ich musste separate grep Anweisungen verwenden, da die Optionen, die ich übergeben musste, bei der Verwendung von IP und Datum (benötigen eine Invert-Übereinstimmung) unterschieden. Alternative effektivere Lösungen sind willkommen.

Referenz: - man Seite für grep für Optionen -v und -w

-v, --invert-match 
      Invert the sense of matching, to select non-matching lines. (-v is specified by POSIX.) 

    -w, --word-regexp 
      Select only those lines containing matches that form whole words. The test is that the matching substring must either be at the beginning of the line, or preceded by a 
      non-word constituent character. Similarly, it must be either at the end of the line or followed by a non-word constituent character. Word-constituent characters are 
      letters, digits, and the underscore. 

-Update-1: -

grep unterstützt auch Art und Weise Daten über eine lange Dauer zum Beispiel zu ignorieren, wenn grep -v "2016-05-2[2-7]" gegeben ignoriert alle Protokolleinträge vom 22. Mai bis 27. Mai aus dem Protokoll.

-Update-2: -

Für das Beispielprotokoll im OP zur Verfügung gestellt, ich habe die Beobachtung gemacht, wie folgt.die IP "211.128.236.70" ist in mehreren Daten und die letzte Instanz nicht in heutigen Tagen ist die in Zeilennummer 4675 (cat -n /home/dude/5000.txt | grep "2016-06-01 23:16:30")

$ time tac /home/dude/5000.txt | grep -w "211.128.236.70" | grep -vw "2016-06-02" | head -1 
2016-06-01 23:16:30 +0200 -> 211.128.236.70 

real 0m0.005s 
user 0m0.004s 
sys  0m0.006s 
+0

Thx, aber ich würde gerne beim ersten Spiel anhalten. Und ich kann das genaue Datum nicht bestimmen, sondern ein Datum, das nicht heute ist: es kann gestern, vor einer Woche oder vor einem Monat nicht bekannt sein. – Konstantin

+0

@Konstantin: Meine Antwort funktionierte in der von Ihnen bereitgestellten 5000-Zeilen-Beispieldatei. – Inian

+0

@Konstantin: Akzeptieren Sie die beste Antwort Ihrer Bequemlichkeit, so dass dieser Beitrag als gelöst gekennzeichnet werden kann, in einer Weise wird es nützlich sein für andere – Inian

0

Dies wird für die Zeilen mit IP in grep, und entfernen Sie dann die Zeilen mit tod ays Datum. (Generalisierte Weise) und Kopf, um nur den ersten davon zu hacken.

tac data |grep "86.171.55.134" |grep -v "`date +%Y-%m-%d`" |head -1 
2016-06-02 11:46:33 +0200 -> 86.171.55.134 
Verwandte Themen