根据日期字符串在PowerShell中过滤和排序日志行

时间:2017-04-27 13:49:57

标签: powershell filtering streamreader

我有两个单独的脚本来执行此过程。第一个查看大型日志并过滤掉那个长的特定行并将它们放入一个新的日志文件中。然后我有第二个脚本,从新的日志文件中读取每行的前十个字符(这些实际上代表日志条目的日期为yyyy-mm-dd),并根据该日期,它将整个行放入将文件记录到新目标文件中,该文件的名称基于该日期(targetfile-yymmdd.log)。由于我的原始日志往往包含跨越两个或更多日期的日期,因此我需要对它们进行排序,以便每个最终日志文件仅包含一个日期的条目,以便文件名反映该实际日期。

我想将这两个脚本合并为一个:从日志中读取行,检查它是否与过滤器匹配,如果匹配,检查前十个字符,然后将行转储到相应的目标文件中。以下是基础知识,正如我现在所拥有的那样:

脚本1读取大型日志文件(标准Apache htaccess日志)并根据特定模式过滤掉行,将它们放入新文件中:

$workingdate = [today's date as yymmdd ]
Get-Content "completelog-$workingdate.log" -ReadCount 200000 | 
foreach {
     $_ -match "(/(jsummit|popin|esa)/)" | 
     Add-Content "D:\logs\filteredlog-$workingdate.log"
}

脚本2然后浏览新文件并查看每行的前十个字符,其中包含标准日期yyyy-mm-dd。它通过名称targetfile-ddmmyy.log将该行复制到新文件中,其中日期基于该行的实际日期:

$file = "filtered-$workingdate.log" (where $workingdate is today's date as yymmdd)
$streamReader = New-Object System.IO.StreamReader -Arg "$file"
while($line = $streamReader.ReadLine()){
    $targetdate = $([datetime]::ParseExact($line.Substring(0,10), 'yyyy-mm-dd', $null).ToString('yymmdd'))
    $targetfile = "targetfile-$targetdate.log"
    $line | Add-Content $targetfile
}

很明显,这两个工作正常,但由于我的日志文件超过20GB,我想减少完成这些日志所需的时间(两次)。

1 个答案:

答案 0 :(得分:1)

您可以使用每个匹配的行并跳过创建中间文件。

(Get-Content "completelog-$workingdate.log" -ReadCount 200000) | 
%{ $_ } | ?{ $_ -match $REGEX } | %{
    $targetdate = '{0:yyMMdd}' -f $(Get-Date $_.Substring(0,10));
    $_ | Add-Content "targetfile-$targetdate.log"
}

虽然我不确定这会改善整体表现。在5MB文件上测试这个大约需要100秒。