Использование памяти Powershell - PullRequest
2 голосов
/ 05 марта 2009

Я не новичок в Powershell, поэтому, пожалуйста, не наказывайте меня :-) Итак, у меня есть несколько довольно больших файлов журнала (600 МБ), которые мне нужно обработать, мой скрипт по существу удаляет те строки, которые содержат «Message Received», затем разбивает эти строки на токены и выводит несколько токенов в файл вывода. *

Логика сценария в порядке (хотя я уверен, что он мог бы быть более эффективным), но проблема в том, что когда я записываю строки в выходной файл, а затем файл постепенно увеличивается, объем используемой PowerShell памяти также увеличивается до точка истощения памяти.

Кто-нибудь может подсказать, как я могу остановить это? Я думал о том, чтобы разбить журнал на временный файл, скажем, всего 10 Мб, а затем обработать временный файл?

Вот мой код, любая помощь, которую вы, ребята, могли бы оказать, была бы фантастической: -)

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 ]

7 голосов
/ 05 марта 2009

Если вы все делаете в конвейере, в памяти должен быть только один объект за раз (одна строка из файла в вашем случае).

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, но будет менее понятным.

2 голосов
/ 02 февраля 2011

пример работающей 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()
0 голосов
/ 05 марта 2009

Вы фактически сохраняете весь файл журнала в памяти вместо последовательного последовательного доступа к нему.

Предполагая, что в вашем файле журнала есть некоторый внутренний разделитель для каждой записи (может быть, новая строка), которую вы будете читать в каждой записи за раз, не сохраняя в памяти больше, чем абсолютно необходимо.

Вы не сможете положиться на встроенный материал 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...