使用 Powershell 2.0 按日期时间截断日志文件

使用 Powershell 2.0 按日期时间截断日志文件

我们有一个简单的日志文件。随着时间的推移,它会变得太大或条目变得不相关。条目具有类似于以下的日期时间前缀:

01/22/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

以下是使用 Streams 的 PowerShell 解决方案。在我的笔记本电脑上处理 1GB 文件大约需要 60 秒(i3 2.5GHz、4GB RAM、5400RPM HDD)。它仍然比日志解析器, 尽管:

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)"
        }

相关内容