【问题标题】:Get powershell regex captures into a table将 powershell 正则表达式捕获到表中
【发布时间】:2011-12-12 08:10:11
【问题描述】:

我正在尝试从一些(大)文本文件中提取一组数据。基本上,每一行看起来像这样:

2011-12-09 18:20:55, ABC.EXE[3b78], The rest of the line...

我想获取大括号之间的日期和位(进程 ID),然后编译一个表。任务的第二阶段是对该表进行分组,以便我获得每个进程 ID 的最早日期,实际上为我提供了每个进程 ID 的第一个日志条目的日期和时间,这有望接近该实例的开始时间过程。

到目前为止我所得到的(为了便于阅读,分成不同的行)

gci -filter *.log -r 
 | select-string '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}), ABC.EXE\[(.{4})' 
 | % { $_.matches } | % { $_.groups } | % { $_.value }

吐出捕获。我想忽略第一个捕获,并将第二个和第三个合并到同一行。

帮助? 请问?

编辑: DOH!无法回答我自己的问题。所以...

好的,我想我是在正确的轨道上。一个 SO 问题here 帮助我获得了我想要的各个部分,即:

$_.matches[0].groups[1].value, $_.matches[0].groups[2].value

然后,一篇 MSDN 文章 here 展示了如何将位“聚集”到一个对象中,从而可以对其进行分组/排序/操作。最终结果

gci -filter *.log | select-string '(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}), ABC.EXE\[(.{4})' 
 | % { new-object object 
  | add-member NoteProperty Name $_.matches[0].groups[1].value -passthru 
  | add-member NoteProperty PId $_.matches[0].groups[2].value -passthru }

相当混乱,所以如果有人知道更清洁的方法,请告诉我。

【问题讨论】:

    标签: regex powershell


    【解决方案1】:

    您可以在 PowerShell v2 中更简单地创建新对象,其中 New-Object cmdlet 支持接收属性哈希表的 -Property 参数:

    New-Object PSObject -Property @{
        Name = $_.matches[0].groups[1].value
        PId = $_.matches[0].groups[2].value
    }
    

    不过,一般来说,我会做一些不同的处理:

    # prepare table
    $data = $(switch -Regex -File filename {
        '^[^,]+' { $date = [datetime]$Matches[0] }
        '(?<=\[)[^\]]+' { $id = $Matches[0] }
        '$' { New-Object PSObject -Property @{
            Date = $date
            PId = $id
        } }
    })
    

    使用switch -regex 已成为(至少对我而言)对文本数据进行快速而肮脏的解析器的好方法。使用-Regex 将运行所有匹配的案例,在这种情况下为所有(因此分离匹配的不同部分只是为了方便)。第一个获取日期和时间并将其存储在变量中(甚至作为DateTime 值);第二个获取进程 ID,第三个在行尾匹配,将它们放在一起。

    不过,这只是个人喜好;我实际上从未使用过Select-String

    $data |
        group PId |
        foreach { New-Object PSObject -Property @{
            PId = $_.Name
            MinDate = @($_.Group | sort Date)[0].Date
        } }
    

    然后使用刚刚编译的数据,按进程 ID 对其进行分组,并输出每个 ID 的最短日期。

    注意,这更像是一种“在代码中看起来不错”的方法。如果您正在处理的文件真的很大,那么您可能需要更高效的方式。

    【讨论】:

    • 太棒了,这就是我想要的东西!我从未在 Powershell 中遇到过 switch 语句。我喜欢这个
    • 你可以做一个Get-Help about_switch。它真的是多才多艺的。
    • 是参数,不是开关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-02
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 2018-03-11
    相关资源
    最近更新 更多