解析包含2个字符串和中间行的行的日志文件

时间:2017-08-09 16:59:45

标签: regex string powershell parsing

我正在尝试解析一些大型日志文件以检测编码错误的发生。识别缺陷是在不同的行上找到一系列字符串,其间有日期。我很难描述事情,所以张贴了一个例子:

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

我将通过多个日志搜索此序列的多个实例:Buffer Failed on,然后是Server_#Server_#可以是任意2位数字,并且永远不会在同一行。 Buffer failed永远不会在找到Server_#之前重复。 介于两者之间的日期和时间,但猜测如果可能的话,它也会被捕获。

理想情况下,我会将这样的内容传递给另一个文件

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

我尝试了一些像

这样的事情
Select-String 'Failed - none(.*?)Response.Response' -AllMatches

但它似乎并不适用于各行。

1 个答案:

答案 0 :(得分:1)

Select-String只能匹配跨越多行的文本,如果它将输入作为单个字符串接收。另外,.通常匹配除换行符之外的任何字符\n)。如果您希望它与换行符匹配,则必须在正则表达式前加上修饰符(?s)。否则,您需要一个包含换行符的表达式,例如[\s\S](.|\n)

最好将匹配固定在expressionDetail而不是实际细节,因为这样可以使匹配更加灵活。

这样的事情可以为您提供您正在寻找的结果:

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

该表达式使用非贪婪匹配和3个捕获组来提取异常详细信息,时间戳和服务器名称。