grep 正規表示式模式在每一行上匹配,其中只有所有匹配項出現並列印在同一行上

grep 正規表示式模式在每一行上匹配,其中只有所有匹配項出現並列印在同一行上

嘗試從日誌檔案中每行提取一些模式。我正在嘗試提取第一個時間戳記和其他兩個或三個匹配項,但我希望能夠僅列印所有匹配項出現的行中的匹配項。是否有一個 grep 命令可以用來執行此操作,或者我是否必須循環遍歷每一行?

我的日誌行是這樣的

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"}]

我希望能夠提取某些群組,例如開頭的時間戳記、「content」和「to_addr」部分。

我想出了這個: grep -oP '(\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2})|"to_addr":"\K(\d+)|"content":\K"(.+?)"' | tr -d '\n'

但我無法僅選擇所有三個模式匹配都存在的行。請問我做錯了什麼?我是不是期待太多了?

答案1

您在模式之間使用 OR |,您需要 AND。

在您的模式中,您正在搜索,"to_addr":"\K(\d+)但在您的示例中, 的值to_addrABCD,因此它與 不匹配,並且和 \d+之間有一個空格,對於 也一樣。"to_addr:"ABCD"content

如果to_addr總是在之前content

grep -P '^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}.*?"to_addr": "\d+.*?"content": ".+?"' 

否則使用前瞻:

grep -P '^\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}(?=.*?"to_addr": "\d+)(?=.*?"content": "(.+?)")' 

如果您只想列印匹配項,我建議使用 Perl 單行程式碼:

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

相關內容