【问题标题】:Searching log file based on pattern, then searching in reverse for specific text根据模式搜索日志文件,然后反向搜索特定文本
【发布时间】:2019-01-23 13:49:11
【问题描述】:

我正在阅读一个如下所示的日志文件:

2019-01-22 13:58:01,524 [1] DEBUG BuH.Sync.Json.ImportSet [(null)] - Import #12344453467612341
2019-01-22 13:58:01,735 [1] DEBUG BuH.Sync.Json.ImportSet [(null)] - Log Stuff
2019-01-22 13:58:01,742 [1] DEBUG BuH.Sync.Json.ImportItem [(null)] - Log Stuff
2019-01-22 13:58:01,761 [1] DEBUG BuH.Sync.Json.BusinessObjects.Adresse [(null)] - Log Stuff
2019-01-22 13:58:01,781 [1] INFO  BuH.Sync.Json.Mapping.Converter2 [(null)] - Log Stuff
2019-01-22 13:58:01,785 [1] ERROR BuH.Sync.Json.Mapping.Json.JsonAdressConverter [(null)] - LOG SYSTEM ERROR CODE
2019-01-22 13:58:01,894 [1] DEBUG BuH.Sync.Json.ImportSet [(null)] - Import #9546181668418643
2019-01-22 13:58:01,896 [1] DEBUG BuH.Sync.Json.ImportSet [(null)] - Log Stuff
2019-01-22 13:58:01,897 [1] DEBUG BuH.Sync.Json.ImportItem [(null)] - Log Stuff
2019-01-22 13:58:01,902 [1] ERROR BuH.Sync.Json.Mapping.Json.JsonAdressConverter [(null)] - LOG SYSTEM ERROR CODE

我可以很容易地找到带有 Get-Content .\JSON.log | ? {($_ | Select-String “Error”)}ERROR 行,但是对于我要准备的电子邮件报告,我需要带有相应 Import # 的行在它之前。我不能使用-context,因为错误和导入编号线之间的线波动。

是否可以通过日志搜索,找到字符串,然后向后搜索另一个字符串?

【问题讨论】:

    标签: powershell


    【解决方案1】:

    如果您过滤日志以仅显示匹配“ERROR”或“Import #”的行,那么您可以使用 ERROR 行的索引来检索前一行。这一行应该是导入行,因为我们过滤日志只是为了显示导入和错误。

    这是根据您发送的日志做出的假设。如果日志包含与这些与我们的查找无关的模式匹配的其他行,这可能不起作用。

    # Get content from log file where line matches 'ERROR' or 'Import #'
    
    $log = gc c:\log.txt | ? { $_ -cmatch 'Import #' -or $_ -cmatch 'ERROR' }
    
    # For each line in log file
    
    foreach($l in $log)
    {
        # If it matches ERROR
    
        if($l -cmatch 'ERROR')
        {
            # Return the previous line
    
            $log[$log.IndexOf($l)-1]
        }
    }
    

    【讨论】:

    • @Adam 仅在这种特殊情况下有效,因为日志行应该是 unqiue(但仅因为时间戳)。否则IndexOf 会返回错误的行。 (您可以使用常规的for 进行迭代,然后您已经有了索引。)此外,这非常不高效,首先转换为数组,然后迭代数组再次,并使用 indexOf,这可能需要一段时间,具体取决于行数。
    【解决方案2】:

    你可以这样做(更好的性能):

    .\JSON.log | foreach {
        # error record found
        if ($_ -match "Error") {
             Write-Host "Import: $importLine"
             Write-Host "Error: $_"
        }
        # if "Import" occurence found, remember it and continue
        elseif ($_ -match "Import #") {
            $importLine = $_
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-23
      • 1970-01-01
      • 2021-09-16
      • 1970-01-01
      • 1970-01-01
      • 2016-05-03
      • 2011-09-18
      相关资源
      最近更新 更多