从日志文件中搜索和分组

Posted

技术标签:

【中文标题】从日志文件中搜索和分组【英文标题】:Search and group from logfile 【发布时间】:2016-04-28 07:54:15 【问题描述】:

我有一个包含许多条目的日志文件。其中一些以日期开头,而另一些则不是。 我想搜索这个/上个月的所有条目 "UpgradeResource] part: 3-V12345678-12-" 在行中并计算按框分组的结果。 实际上从 1 到 9 有 9 个盒子,但如果我们再买一个盒子,就会有 10 或 11……盒子计数器总是在行尾跟着 -1。

我搜索的行如下所示:

2016-04-27 11:49:43,895 信息 [ajp-apr-8009-exec-9] [com.xxx.shared.yyy.UpgradeResource] 部分:3-V12345678-12-5-245,框: 3-V12345678-38-3-1
...
2016-04-27 11:49:43,895 信息 [ajp-apr-8009-exec-9][com.xxx.shared.yyy.UpgradeResource] 部分:3-V12345678-12-4-112,框:3-V12345678 -38-1-1

我的结果输出应该是:

2016 年 3 月 03 日:
盒子1:10次
方框2:123次
方框3:65次

04/2016 月:
方框1:75次
盒子2:13次
方框 3:147 次

我在使用 powershell 方面不是很坚定,并尝试过,但出现错误并认为我的方法不对:

$inputfile = "C:\temp\result.txt"
$matchstring = "(?\d4-\d2-\d2 \d2:\d2:\d2).*UpgradeResource] part: 3-V12345678-12-(?.*?), box: 3-V12345678-38-(\d1)-1"
Get-Content $inputfile | foreach  
    if ($_ -match $matchstring) 
        "" | select @n='Date';e=$matches.date,@n='Key';e=$matches.Key,@n='PD';e=$matches.PD
    

我得到的错误:

"(?\d4-\d2-\d2 \d2:\d2:\d2).*UpgradeResource] 部分:
3-V12345678-12-(?.*?),方框:3-V1001686-38-(\d1)-1" 线分析仪 -
Unbekanntes Gruppierungskonstrukt。
在 C:\temp\count.ps1:16 Zeichen:6
+ if ($_ -match $matchstring)
+ ~~~~~~~~~~~~~~~~~~~~~~
     + CategoryInfo : OperationStopped: (:) [], ArgumentException
     + FullyQualifiedErrorId : System.ArgumentException

【问题讨论】:

您可以在 regex101.com 之类的工具中测试您的正则表达式。您的匹配字符串中有一些?,不被接受。 【参考方案1】:

您遇到的错误是因为(?...) 不是有效的分组构造。如果您想使用命名组(代码的其余部分建议),问号后面必须跟尖括号中的组名 ((?<name>...))。对于非捕获组,它必须后跟一个冒号 ((?:...))。

更多信息请参见here。

您的代码可能看起来像这样:

$inputfile   = 'C:\temp\result.txt'
$matchstring = '(?<date>\d4-\d2-\d2) (?<time>\d2:\d2:\d2)' +
               '.*UpgradeResource] ' +
               'part: 3-V12345678-12-(?<Key>.*?), ' +
               'box: 3-V12345678-38-(?<PD>\d1)-1'
Get-Content $inputfile | Where-Object 
  $_ -match $matchstring
 | ForEach-Object 
  New-Object -Type PSObject -Property  @
    'Date' = $matches.date
    'Time' = $matches.time
    'Key'  = $matches.Key
    'Box'  = 'Box ' + $matches.PD
  
 | Group-Object Date, Box

【讨论】:

【参考方案2】:

这样合适吗?

$inputfile = "C:\temp\result.txt"
$matchstring = "(\d4-\d2-\d2 \d2:\d2:\d2).*UpgradeResource] part: 3-V12345678-12-(.*), box: 3-V12345678-38-(\d1)-1"

Get-Content $inputfile | foreach  
if ($_ -match $matchstring) 

    "" | select @n='Date';e=$matches.1,@n='Key';e=$matches.2,@n='PD';e=$matches.3

给我输出:

Date                                                    Key                                                     PD                                                    
----                                                    ---                                                     --                                                    
2016-04-27 11:49:43                                     5-245                                                   3                                                     
2016-04-27 11:49:43                                     4-112                                                   1   

【讨论】:

是的,这行得通。现在我如何按 PD 计数和分组?我怎样才能得到这个/上个月分组的结果? 您可以在"" | select ..line 中添加| group pd,以便按PD 进行分组。按月分组需要更多的字符串操作,因为group date 将按确切日期分组。 好的,我会尝试更多的东西。我现在已经看到有许多具有相同时间戳的条目。我需要弄清楚,如何才能只计算一个具有相同时间戳的条目。 你可以分解日期,或者只是获取它的信息year-month

以上是关于从日志文件中搜索和分组的主要内容,如果未能解决你的问题,请参考以下文章

无法使用日志轮换从选定的日志文件中搜索字符串

将日志消息存储在数据库表而不是文件中是好还是坏?

是否可以搜索所有节点日志

日志文件跟踪工具

使用 awk getline bash 在指定的时间范围内从日志文件中提取数据

Logstash——解析各类日志文件