У нас есть простой файл журнала. Это становится слишком большим или записи не имеют значения, поскольку они стареют. Записи имеют префикс datetime, подобный этому:

22.01.15 01:54:17 -I- Начать обрабатывать вещи

Иногда записи журнала занимают несколько строк, например:

01/23/15 01:18:00 -E- java.io.IOException: (101) Error between keyboard and chair
     at this.mod.no.worky(what_were_you_thinking:duh)

Мы просто хотим удалить (целые) записи до определенной даты, например, через 30 дней.

Решения, которые усекаются до фиксированного числа строк или байтов, в этом случае не работают.

Самая последняя попытка с ужасной производительностью:

$cutDatePtrn = "^" + (get-date).AddDays(-30).tostring("MM/dd/yy ")
$newStartLine = (select-string -Path $logFile -Pattern $cutDatePtrn -Quiet -List).LineNumber
$tmp = $logFile + '.tmp'
get-content $logFile | select -skip $newStartLine | out-file $tmp

1 ответ1

2

Вот решение PowerShell с использованием потоков. Для обработки файла 1 ГБ на моем ноутбуке требуется ~ 60 секунд (i3 2,5 ГГц, 4 ГБ ОЗУ, жесткий диск 5400 об / мин). Это все еще в три раза медленнее, чем LogParser, хотя:

LOGPARSER "Select Text from C:\Path\To\log.file where Text like '01/22/15%'" -i:TEXTLINE -q:Off
$LogFolder = 'c:\Path\To\Log\Folder'
$Filter = '*.log'
$Postfix = '.tmp'
$cutDatePtrn = '^' + (Get-Date).AddDays(-30).ToString('MM/dd/yy')

# Iterate over each log file in the $LogFolder
Get-ChildItem -LiteralPath $LogFolder -Filter $Filter |
    ForEach-Object {
        Write-Host "Current file: $($_.FullName)"
        $InFile = New-Object -TypeName System.IO.StreamReader -ArgumentList $_.FullName

        Write-Host 'Processing file...'

        $WriteFile = $false
        while(($line = $InFile.ReadLine()) -ne $null)
        {
            if((-not $WriteFile) -and ($line -notmatch $cutDatePtrn))
            {
                continue
            }
            elseif((-not $WriteFile) -and ($line -match $cutDatePtrn))
            {
                Write-Host 'Found match:'
                Write-Host $line

                $WriteFile = $true
                $TmpFile = $_.FullName + $Postfix

                Write-Host "Creating new temporary file: $TmpFile"
                $OutFile = New-Object -TypeName System.IO.StreamWriter -ArgumentList $TmpFile, $false
            }

            $OutFile.WriteLine($line)
        }

        Write-Host 'Done processing, cleaning up...'
        if($OutFile)
        {

            $OutFile.Flush()
            $OutFile.Close()
            $OutFile.Dispose()
        }

        $InFile.Close()
        $InFile.Dispose()

        if(Test-Path $TmpFile -PathType Leaf)
        {
            Write-Host "Deleting original file: $($_.FullName)"
            Remove-Item -Path $_.FullName -Force

            Write-Host "Renaming temporary file: $TmpFile -> $($_.FullName)"
            Rename-Item -Path $TmpFile -NewName $_.FullName -Force
        }

        Write-Host "Finished processing file: $($_.FullName)"
        }

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .