Parse log file for lines containing 2 strings and

2019-08-01 05:59发布

I am trying to parse some large log files to detect occurrences of a coding bug. Identifying the defect is finding a sequence of strings on different lines with a date in between. I am terrible at describing things so posting an example:

    <Result xmlns="">
    <Failure exceptionClass="processing" exceptionDetail="State_Open::Buffer Failed - none">
      <SystemID>ffds[sid=EPS_FFDS, 50] Version:01.00.00</SystemID>
      <Description>Lo
ck Server failed </Description>
    </Failure>
  </Result>
</BufferReply>
7/22/2017 8:41:15 AM | SomeServer | Information | ResponseProcessing.TreatEPSResponse() is going to process a response or event. Response.ServiceID [Server_06] Response.Response [com.schema.fcc.ffds.BufferReply]

I will be searching for multiple instances of this sequence through multiple logs: Buffer Failed on followed by Server_#. The Server_# can be any 2-digit number and will never be on the same line. Buffer failed will never repeat prior to Server_# being found. The date and time that is in between but guessing that if this is possible it would be captured also.

Ideally, I would pipe something like this to another file

Buffer Failed - none"   7/22/2017 8:41:15 AM [Server_06]

I have attempted a few things like

Select-String 'Failed - none(.*?)Response.Response' -AllMatches

but it doesn't seem to work across lines.

1条回答
Fickle 薄情
2楼-- · 2019-08-01 06:21

Select-String can only match text spanning multiple lines if it receives the input as a single string. Plus, . normally matches any character except line feeds (\n). If you want it to match line feeds as well you must prefix your regular expression with the modifier (?s). Otherwise you need an expression that does include line feeds, e.g. [\s\S] or (.|\n).

It might also be advisable to anchor the match at expressionDetail rather than the actual detail, because that makes the match more flexible.

Something like this should give you the result you're looking for:

$re = '(?s)exceptionDetail="(.*?)".*?(\d+/\d+/\d+ \d+:\d+:\d+ [AP]M).*?\[(.*?)\] Response\.Response'

... | Out-String |
    Select-String -Pattern $re -AllMatches |
    Select -Expand Matches |
    ForEach-Object { '{0} {1} [{2}]' -f $_.Groups[1..3] }

The expression uses non-greedy matches and 3 capturing groups for extracting exception detail, timestamp and servername.

查看更多
登录 后发表回答