快速从大文件中获取唯一记录

时间:2018-05-08 09:16:08

标签: powershell

我有大文件(每个至少20 MB)我需要查找字符串M(\d{10})

以下是我正在使用的脚本:

Get-Content -Path Test.log | %{ [Regex]::Matches($_, "M(\d{10})") } | %{ $_.Value } | select -Unique

这需要花费大量时间和更多CPU,请建议如何以更低的CPU使用率/更快的速度获得结果。

3 个答案:

答案 0 :(得分:2)

简单地衡量一下自己(最小化缓存效果差异,首先重复):

Measure-Command {Get-Content -Path Test.log | %{ [Regex]::Matches($_, "M(\d{10})") } | %{ $_.Value } | select -Unique}

Measure-Command {Get-Content -Path Test.log | %{ [Regex]::Matches($_, "M(\d{10})") } | %{ $_.Value } | select -Unique}

Measure-Command {sls -Path Test.log  "M(\d{10})"  | %{ $_.Matches.Groups[1].Value } | select -Unique}

答案 1 :(得分:1)

(可能)使用管道内存有效的,但是使用速度慢

要加快处理速度,

  • 避免管道,但这仅是您的数据可以整体装入内存的唯一选择-20 MB不会有问题文件。

  • 分别直接使用.NET框架类型及其方法,通常比使用 cmdlet 更快。

将这些见解应用于您的情况(PSv3 +语法):

[regex]::Matches(
   [IO.File]::ReadAllText($PWD.ProviderPath + '/Test.log'), 
   'M\d{10}'
).Value | Select-Object -Unique

请注意,为方便起见,Select-Object -Unique仍使用流水线以获取唯一的出现次数,但是假设是处理的大部分(提取正则表达式匹配项)位于该声明。

答案 2 :(得分:0)

我不会多次使用Foreach-Object,而是使用Select-String

(Get-Content -Path Test.log | Select-String "(?<=M)\d{10}").Matches.Value | select -Unique