Ich versuche, aus einer Protokolldatei zeilenweise einige Muster zu extrahieren. Ich versuche, den ersten Zeitstempel und zwei oder drei weitere Übereinstimmungen zu extrahieren, möchte aber nur die Übereinstimmungen aus den Zeilen drucken können, in denen alle Übereinstimmungen vorkommen. Gibt es einen einzelnen Grep-Befehl, mit dem ich dies tun kann, oder muss ich jede Zeile durchlaufen?
Meine Logzeile sieht so aus
2018-08-07 08:55:20 ERROR[t-dispatcher-24] - Error while processing message: code:[RequestTimeout], message:[{"from_addr_type": null, "transport_name": "999_abc_999_2_1", "in_reply_to": null, "group": null, "timestamp": "2018-08-07 07:55:19.795748", "from_addr": "341231231234", "message_type": "user_message", "helper_metadata": {}, "to_addr": "ABCD", "to_addr_type": null, "session_id": "157692", "content": "0013091779", "routing_metadata": {}, "message_version": "20110921", "transport_type": "XXXX", "provider": "abc_somewhere", "transport_metadata": {"abc_somewhere_XXXX": {"clientId": "XXXX157692", "starCode": "999", "session_id": "157692", "phase": "2", "dcs": "15", "requestId": "157692"}}, "session_event": "resume", "message_id": "5d9cab5353ff449783a737e8390a690b"}]
Ich möchte in der Lage sein, bestimmte Gruppen zu extrahieren, wie etwa den Zeitstempel am Anfang, die Abschnitte „Inhalt“ und „An_Adresse“.
Mir ist Folgendes eingefallen:
grep -oP '(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})|"to_addr":"\K(\d+)|"content":\K"(.+?)"' | tr -d '\n'
Aber ich kann nicht nur die Zeilen auswählen, in denen alle drei Musterübereinstimmungen vorhanden sind. Bitte, was mache ich falsch? Erwarte ich zu viel?
Antwort1
Sie verwenden ein ODER |
zwischen Ihren Mustern, Sie möchten ein UND.
In Ihrem Muster suchen Sie nach, aber in Ihrem Beispiel ist "to_addr":"\K(\d+)
der Wert von, also stimmt er nicht mit überein und zwischen und steht ein Leerzeichen , dasselbe gilt für .to_addr
ABCD
\d+
"to_addr:
"ABCD"
content
Wenn to_addr
steht immer vor content
:
grep -P '^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.*?"to_addr": "\d+.*?"content": ".+?"'
Andernfalls verwenden Sie Lookaheads:
grep -P '^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}(?=.*?"to_addr": "\d+)(?=.*?"content": "(.+?)")'
Wenn Sie nur die Übereinstimmungen drucken möchten, schlage ich einen Perl-Einzeiler vor:
perl -ane 'print "$1\t$2\t$3\n" if (/^(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})(?=.*?"to_addr": "(\d+))(?=.*?"content": "(.+?)")/)' file