如何更快地过滤具有一定数量字符的文件行?

时间:2017-04-07 19:16:23

标签: powershell powershell-v4.0

所以我有一些相当大的平面文件。

我正在尝试使用PowerShell,只选择具有预期分隔符数量的行并将它们输出到文件中。

这有效:

nextLine()

然而,它是RBAR,因此它不是针对500mb文件的最有效方法。有什么建议吗?

扎克

3 个答案:

答案 0 :(得分:3)

您已经在使用流,这对于一般的大文件非常有用,并且适用于这种情况。

您正在每个循环中读取两行!。这应该是你写错了行文件。使用您为该行存储的变量

$sw.WriteLine($line)

以下一行也是取得进步的好地方。

$gl = ($line.ToCharArray() | Where-Object {$_ -eq '|'} | Measure-Object).Count

这里有一些代价高昂的行动。将该行拆分为char数组,Measure-Object为大数组。我将测试是否可以对此进行基准测试,但使用一些正则表达式方法应该更快

$gl = ([regex]::Matches($line,"\|")).count

最后,如果您愿意删除它,请删除Write-Host行。将数据写入控制台也是一种性能问题。

您必须为此重构代码,我不知道它是否会更快但您现在可以使用-ReadCountGet-Content一起提取大量文件好。

答案 1 :(得分:3)

以下是替换正则表达式的替代方案。

$gl = ($line -replace '[^|]','').length

如果您可能有嵌套分隔符,则可以更进一步。

$gl = ($line -replace '[^|"]','' -replace '"\|"',"").length

答案 2 :(得分:2)

这么多代码可以做一些如此简单的事情。首先看看Select-String处理文件的速度有多快:

Select-String $importfile -Pattern '([^|]+\|){350}' | Select line | Set-Content $goodfile

如果您想要更快的速度,请尝试将ReadCount传递给Get-Content,这将分批流式传输您的文件。像这样:

Get-Content $importfile -ReadCount 1000 | ? {$_ -match '([^|]+\|){350}'} | Set-Content $goodfile