首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Powershell regex从日志文件中提取数据

Powershell regex从日志文件中提取数据
EN

Stack Overflow用户
提问于 2016-08-19 15:11:49
回答 1查看 2K关注 0票数 0

使用脚本从日志文件中提取数据;搜索、查询和执行时间中的术语。

从日志文件中获取示例

代码语言:javascript
复制
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编码的。

我正在进行的工作脚本加载日志文件。

代码语言:javascript
复制
foreach ($line in [System.IO.File]::ReadLines($filename)) 

然后URLdecods每一行并删除一个长的securityinfo字符串

代码语言:javascript
复制
$VarURLDecoded = [System.Web.HttpUtility]::UrlDecode($line) -replace "SecurityInfo=.*"

现在我正努力用RegEx来提取以下内容:日期+时间、MaxResault=xxxxxxx、Text=(?):?)以及以ms为单位的请求完成的时间,如下所示。

代码语言:javascript
复制
$findText = $VarURLDecoded | select-string -Inputobject {$_} -pattern 

我有一些部分的正则表达式。

代码语言:javascript
复制
'(\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

但是无法确定连接它们的和语法,包括第二行的持续时间记录。要么使用下面一行后面的事实,要么使用具有适当时间戳的事实。

一旦基本的regex开始工作,我就可以通过添加命名组并将结果导出到哈希表来增加复杂性。

EN

回答 1

Stack Overflow用户

发布于 2016-08-19 16:31:07

从发布的日志判断,不需要对其进行解码,因为没有%xx-encoded字符。

对于文本处理,不需要像[System.IO.File]这样的低级别的东西。

需要额外的一行,所以让我们使用-context before, after参数。

代码语言:javascript
复制
$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现在是一个对象数组,每个对象如下:

名称值

或者,考虑到select- string的模式匹配对于复杂的模式可能比较慢,让我们使用简单的字符串进行匹配,使用? (Where-Object的别名)筛选,然后处理结果:

代码语言:javascript
复制
$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] }
    }
}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39042461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档