带有switch
选项的-File
语句是在PowerShell [1] 中处理大型文件的最快方法:
& {
switch -File $infile -Regex {
$match_regex {
# Join the what all the capture groups matched,trimmed,with a tab char.
$Matches[1..($Matches.Count-1)].Trim() -join "`t"
}
}
} | Out-File $outFile # or: Set-Content $outFile (beware encoding issues)
通过文本输出,Out-File
和Set-Content
可以互换使用,但是在 Windows PowerShell 中,它们默认情况下使用不同的字符编码(UTF-16LE与Ansi);根据需要使用-Encoding
; PowerShell Core 始终使用无BOM的UTF-8。
注意:
-
要跳过标头行或单独捕获它,请为其提供单独的正则表达式,或者,如果标头也与数据行正则表达式匹配,请在初始化行索引变量之前switch
语句(例如$i = 0
),然后在处理脚本块(例如if ($i++ -eq 0) { ... }
)中检查并递增该变量。
在.Trim()
返回的数组中的每个字符串上,-
$Matches[1..($Matches.Count-1)]
被隐式调用 ;此功能称为member enumeration
-
switch
语句包含在script block调用的& { ... }
(call operator (&
)({ ... }
)中的原因是 compound 语句,例如switch
/ while
,foreach (...)
,...作为管道输入-参见{{ 3}}。
关于您尝试过的事情:
正如this GitHub issue所指出的那样,您不应使用$Input
作为用户变量-它是由PowerShell管理的iRon,实际上,您分配给它的任何内容都是安静地丢弃。
automatic variable指出:
AdminOfThings展示了如何直接将-join
与$Matches
数组一起使用,如上所述。
一些助手:
Join-Str($matches)
您应该改用Join-Str $matches
:
在PowerShell中,像外壳命令一样调用函数 -foo arg1 arg2
-不像C#方法调用 -foo(arg1,arg2)
;参见Lee_Daily。
如果使用,
分隔参数,则将构造一个 array ,该函数会将其视为单个参数。
为防止意外使用方法语法,请使用Get-Help about_Parsing
或更高版本,但请注意其其他效果。
| Out-Null
几乎总是更快的输出抑制方法是使用$null = ...
。
[1]与问题中的Get-Content
+ ForEach-Object
方法相比,Mark(OP)报告了极大的提速(switch
解决方案需要7.7分钟。 4GB的文件)。
尽管switch
解决方案在大多数情况下可能足够快,但Set-StrictMode -Version 2
显示的解决方案对于高迭代次数可能更快; this answer与switch
解决方案进行了对比,并显示了具有不同迭代次数的基准。
除此之外,用C#编写的已编译解决方案是进一步提高性能的唯一方法。
,
这是我的工作代码的高层次。注意,使用System.IO.StreamReader对于使处理时间达到可接受的水平至关重要。感谢所有帮助我到达这里的帮助。
$posts
本文链接:https://www.f2er.com/3135215.html