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

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

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

3回复

使用powershell捕获数组中的正则表达式匹配

我们有一个从mac用户计算机导出的大型.vcf。 导出联系人的过程导致单个.vcf将所有联系人聚集到一个文件中。 我使用notepad ++将“BEGIN:”的所有实例替换为“\\ nBEGIN:”,以便我今晚可以睡觉。 计划是将每个匹配的reg表达式放入一个数组中,然后将每个字符
1回复

在PowerShell中的正则表达式

我需要从出现在两个值之间的文本文件中检索一个字符串。 例如,我需要检索< postcode >W12 FGS < /postcode >之间的字符串,然后在该字符串中放置一个空格,因此它看起来像< postcode >W12 FGS < /postco
1回复

Powershell中的正则表达式

我正在编写一个可以解析文本的脚本,该文本完全没有结构,这意味着我愿意提取的内容没有特定的结构。 该脚本必须使用REGEX来查找特定文章的数量: 正常结构= “ 3个球” “ 2个球和6个娃娃” 我可以使用这样的正则表达式((\\d+)."+$article+"
3回复

从PowerShell中的正则表达式搜索中获取捕获的数组

假设我有以下字符串: 我有这个正则表达式模式: 在PowerShell中,如何获取内容为{"h", "bfh"}的数组?
2回复

Powershell正则表达式捕获,直到“空白”

这是当前的脚本: 这样可以成功捕获“群集:”和“元数据:”之间的所有内容。 这是输出的一部分(突出显示我要捕获的部分) 除非输出有时更改并且“ Meta Data:”不再存在,否则这将完美地工作。 我希望能够捕获到第一行空白为止,或者从突出显示的第一行中仅捕获1个空格而没有
1回复

PowerShell正则表达式捕获差异

目的是仅从字符串中获取SPACE字符之前的前导数字。 当我在PowerShell中使用-replace时,会包含前导字母字符。 为什么有什么不同? 这不会在产生的regex101.com上发生。 不重复 问题不在于如何获取号码。 问题是为什么'aasdf'与\\d匹配
1回复

带有“。”的PowerShell正则表达式

我想用PowerShell在循环中替换部分字符串的一部分 示例字符串 testvm029.vmxxx 我想替换.vmxxx中的所有内容。 每个字符串都有另一个长度,但是所有结尾都是.vm...因此结果应该是: testvm029 我尝试了以下脚本: Foreach(
2回复

Powershell简单正则表达式捕获组未捕获

我希望在Powershell中使用这个简单的正则表达式会遇到最困难的时期。 我想捕获此简单匹配表达式的(\\d+)组: 问题是无论我尝试什么,都未定义$myvar[1] 。 当我在崇高文字替换工具中运行此正则表达式时,它会正确捕获组。 这个简单的脚本在做什么错?
1回复

Powershell正则表达式?

所以我有一个日志文件,其中包含从1个文件夹复制到另一个文件夹的文件列表。 例如, 8月12日17:23:51 C:\\ Users \\ Folder_1 \\ File1.exe移至D:\\ Users \\ Folder_1 \\ File1.exe 8月12日17:24:33
1回复

正则表达式PowerShell

powershell中用于读取“ JPEG”和“ 5”之间的值的正则表达式是什么? 我使用以下正则表达式获取值,但它不起作用。在“ JPEG”和“ 5”之间获取值的最佳模式是什么。