需要帮助改善PowerShell中分隔的文本解析脚本的执行
问题描述:
我有必要通过大型管道分隔的文件解析来算,其第5列符合,不符合我的标准的记录数。需要帮助改善PowerShell中分隔的文本解析脚本的执行
PS C:\temp> gc .\items.txt -readcount 1000 | `
? { $_ -notlike "HEAD" } | `
% { foreach ($s in $_) { $s.split("|")[4] } } | `
group -property {$_ -ge 256} -noelement | `
ft –autosize
此命令我想要做什么,这样返回的输出:
Count Name ----- ---- 1129339 True 2013703 False
然而,对于一个500 MB的测试文件,这个命令需要约5.5钟如通过测量命令测量运行。一个典型的文件超过2GB,等待20分钟以上的时间不合需要很长。
你看到的方式,以提高该命令的性能?
例如,有没有办法来确定获取内容的ReadCount最佳值?没有它,完成相同的文件需要8.8分钟。
答
使用@吉斯利的提示,这里是我结束了剧本:
param($file = $(Read-Host -prompt "File"))
$fullName = (Get-Item "$file").FullName
$sr = New-Object System.IO.StreamReader("$fullName")
$trueCount = 0;
$falseCount = 0;
while (($line = $sr.ReadLine()) -ne $null) {
if ($line -like 'HEAD|') { continue }
if ($line.split("|")[4] -ge 256) {
$trueCount++
}
else {
$falseCount++
}
}
$sr.Dispose()
write "True count: $trueCount"
write "False count: $falseCount"
它产生在大约一分钟,这符合我的性能要求同样的结果。
答
只需添加使用的StreamReader通过一个非常大的IIS日志文件中读取另一个例子输出所有独特的客户端的IP地址和一些PERF指标。
$path = 'A_245MB_IIS_Log_File.txt'
$r = [IO.File]::OpenText($path)
$clients = @{}
while ($r.Peek() -ge 0) {
$line = $r.ReadLine()
# String processing here...
if (-not $line.StartsWith('#')) {
$split = $line.Split()
$client = $split[-5]
if (-not $clients.ContainsKey($client)){
$clients.Add($client, $null)
}
}
}
$r.Dispose()
$clients.Keys | Sort
针对Get-Content
小性能对比:
的StreamReader :完成5.5秒,PowerShell.exe:35328 KB RAM。
获取内容:完成23.6秒。 PowerShell.exe:1,110,524 KB RAM。
您是否试过StreamReader?我认为Get-Content会在完成任何事情之前将整个文件加载到内存中。 – Gisli 2012-01-17 21:52:25
你的意思是通过导入System.IO? – neontapir 2012-01-17 21:59:23
是的,如果可以的话,请使用.net框架。我曾经习惯读取SQL Server生成的大型日志文件,结果良好。我不知道PowerShell中有任何其他方式来有效地读取大文件,但我不是专家。 – Gisli 2012-01-17 22:08:59