我正在尝试解析一些大型日志文件以检测编码错误的发生。识别缺陷是在不同的行上找到一系列字符串,其间有日期。我很难描述事情,所以张贴了一个例子:
<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
但它似乎并不适用于各行。
答案 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个捕获组来提取异常详细信息,时间戳和服务器名称。