我们有一个简单的日志文件。随着时间的推移,它会变得太大或条目变得不相关。条目具有类似于以下的日期时间前缀:
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)"
}