处理脚本以从日志文件中提取数据;搜索查询和执行时间中的术语。
日志文件中的样本
19/08/2016 09:08:00 [100] ACTION%3DQuery%26MaxResults%3D9999%26abridged%3Dtrue%26abridgedmeta%3Ddatabase%26printfields%3DIM_DOCNUM,IM_VERSION%26combine%3Dfieldcheck%26databasematch%3DDATABASE_1,DATABASE-2%26Text%3D((pep21556)%3AIM_DOCNAME)%26fieldtext%3D(WILD%7BWORK%7D%3AIM_PRJ_SUBTYPE+AND+WILD%7BWEBDOC%7D%3AIM_CLASS)+AND+BIASDATE%7B1471612079e,2592000,20%7D%3Aautn_date+AND+BIASDATE%7B1471612079e,63072000,20%7D%3Aautn_date%26anyLanguage%3Dtrue%26TimeoutMS%3D60000
19/08/2016 09:08:00 [100] Request completed in 12 ms.
19/08/2016 09:08:28 [103] Request from 10.1.1.131
日志文件是URL编码的。
我的工作进度脚本加载日志文件
foreach ($line in [System.IO.File]::ReadLines($filename))
然后URLdecods每一行并删除一个长的securityinfo字符串
$VarURLDecoded = [System.Web.HttpUtility]::UrlDecode($line) -replace "SecurityInfo=.*"
现在我正在努力与RegEx提取以下内容:日期+时间,MaxResault = xxxxxxx,文字=((??????????):???????)和时间以ms为单位,请求在以下行中完成。
$findText = $VarURLDecoded | select-string -Inputobject {$_} -pattern
我有一些部分正则表达式。
'(\d{2}/\d{2}/\d{4} \d{2}:\d{2}:\d{2})' will find 19/08/2016 09:08:00
'MaxResults=(\d*)' will find MaxResults=9999
'(?<Text>&Text=\(\([^()]*\)\:[^()]*\))' will find &Text=((campeau):IM_DOCNAME)
'(\d* ms)' will find the xx ms
但无法弄清楚加入它们的AND语法,包括第二行的持续时间记录。要么使用它遵循下面的线的事实,要么使用它具有适当时间戳的事实。
一旦我获得了基本的正则表达式,我就可以通过添加命名组并将结果导出到哈希表来增加复杂性。
答案 0 :(得分:2)
根据发布的日志判断,由于没有%xx
个编码字符,因此无需对其进行解码。
对于文本处理,不需要像[System.IO.File]
这样的低级别的东西
需要额外的一行,所以让我们使用-context before, after
参数。
$report = select-string -path $filename -context 0,1 -pattern (
'^(?<date>.+?) ' +
'(?<time>.+?) .+?' +
'&MaxResults=(?<results>\d+).+?' +
'&Text=(?<text>[^&]+)') |
%{
$nextLine = $_.Context.PostContext[0]
$g = $_.matches[0].groups
@{
date = $g['date'].value
time = $g['time'].value
results = $g['results'].value
text = $g['text'].value
duration = if ($nextLine -match 'completed in (\d+) ms') { $matches[1] }
}
}
$report
现在是一个对象数组,每个对象如下:
Name Value ---- ----- date 19/08/2016 time 09:08:00 duration 12 results 9999 text ((pep21556):IM_DOCNAME)
或者,考虑到select-string的模式匹配可能会因复杂模式而变慢,让我们使用简单字符串进行匹配,使用?
(Where-Object
的别名)进行过滤,然后处理结果:
$report = select-string -path $filename -context 0,1 -pattern '&MaxResults=' -simpleMatch |
?{ $_.Line -match (
'^(?<date>.+?) ' +
'(?<time>.+?) .+?' +
'&MaxResults=(?<results>\d+).+?' +
'&Text=(?<text>[^&]+)')
} | %{
$nextLine = $_.Context.PostContext[0]
$m = $matches # $matches is set by the above -match
@{
date = $m['date']
time = $m['time']
results = $m['results']
text = $m['text']
duration = if ($nextLine -match 'completed in (\d+) ms') { $matches[1] }
}
}