Powershell内存使用情况

时间:2009-03-05 10:56:31

标签: memory powershell

我向Powershell提出了一个菜鸟,所以请不要惩罚我:-) 所以我有一些我需要处理的相当大的日志文件(600mb),我的脚本实际上删除了那些包含“Message Received”的行,然后标记这些行并将一些令牌输出到输出文件。

脚本的逻辑很好(虽然我确定它可能更有效)但问题是,当我将行写入输出文件并且文件随后变得更大时,powershell使用的内存量也增加到记忆耗尽的重点。

任何人都可以建议我如何阻止这种情况发生?我想把日志分解成一个只有10mb的临时文件然后处理临时文件呢?

继承我的代码,你们给予的任何帮助都会很棒: - )

Get-Date | Add-Content -Path d:\scripting\logparser\testoutput.txt


$a = Get-Content D:\scripting\logparser\importsample.txt 


foreach($l in $a){
#$l | Select-String -Pattern "Message Received." | Add-Content -Path d:\scripting\logparser\testoutput.txt
if
    (($l | Select-String -Pattern "Message Received." -Quiet) -eq "True")

    {
    #Add-Content -Path d:\scripting\logparser\testoutput.txt -value $l
    $var1,$var2,$var3,$var4,$var5,$var6,$var7,$var8,$var9,$var10,$var11,$var12,$var13,$var14,$var15,$var16,$var17,$var18,$var19,$var20 = [regex]::split($l,'\s+')
    Add-Content -Path d:\scripting\logparser\testoutput.txt -value $var1" "$var2" "$var3" "$var4" "$var16" "$var18

    }
else
    {}
}   
Get-Date | Add-Content -Path d:\scripting\logparser\testoutput.txt

3 个答案:

答案 0 :(得分:7)

如果您在管道中执行所有操作,则一次只能有一个对象(在您的情况下来自文件的一行)需要在内存中。

Get-Content $inputFile | Where-Object { $_ -match "Message Received" } |
  foreach-object -process {
  $fields = [regex]::split($_,'\s+') # An array is created
  Add-Content -path $outputFile -value [String]::Join(" ", $fields[0,1,2,3,15,17])
}

$fields[0,1,2,3,15,17]创建一个给定索引为$fields的数组。

这也可以在单个管道中使用表达式而不是传递给Select-Object的属性名称来完成,但不太清楚。

答案 1 :(得分:2)

一个有效的PowerShell示例:

$csvFile = "c:\test.txt"

$file_reader = [System.IO.File]::OpenText($csvFile)
$row = "";
while(($row = $file_reader.ReadLine()) -ne $null) 
{ 
    # do something with '$row' 
    Write-Host row: $row
}
$file_reader.Close()

答案 2 :(得分:0)

您有效地将整个日志文件存储在内存中,而不是逐位顺序访问它。

假设您的日志文件对于每个条目(可能是新行)都有一些内部分隔符,您每次都会在每个条目中读取内容分隔符,而不是在内存中保留更多内容而非绝对必要。

你将无法依赖内置的PowerShell东西,因为它会造成愚蠢的影响。

你必须为我的代码示例道歉,我的PowerShell有点生疏。

var $reader = Create-Object "System.IO.StreamReader" testoutput.txt
var $s = ""
while(($s = reader.ReadLine())!=null)
{ 
    // do something with '$s' 
    // which would contain individual log entries.
}
$reader.Close()