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

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问题帮助我获得了我想要的各个部分,即:

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

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

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 }

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

===============>>#1 票数:4 已采纳

您可以在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的最小日期ID。

注意,这更像是“看起来不错的代码”方法。 如果你正在处理的文件非常大,你可能想要更高效的方法。

  ask by His Royal Redness translate from so

未解决问题?本站智能推荐: