Powershell按日期和时间排序

时间:2018-09-17 16:20:38

标签: powershell sorting datetime

我想说的是(我是企鹅)我不是Windows也不是Powershell,但这不应该阻止我帮助Windows团队。

我需要合并两个日志并按日期和时间对其进行排序。我认为将它们组合起来应该足够简单,但是按日期和时间进行排序似乎使我有点失望。

我正在使用的日志没有相同的列数,因此我在某种程度上对日志进行规范化,以尝试通过logline [3,4]进行排序,这是日期和时间。

"SMTPD" 4416    2476943 "2018-09-11 23:53:37.410"   "1.1.1.1"   "SENT: 221 goodbye"
"TCPIP" 4308    "2018-09-11 23:59:47.255"   "TCP - 1.1.1.2 connected to 1.1.1.1:25."
"SMTPD" 4308    2476952 "2018-09-11 23:22:47.255"   "1.1.1.1"   "SENT: 220 mx9.bobdestroyer.com ESMTP"
"SMTPD" 4416    2476952 "2018-09-11 23:35:47.255"   "1.2.3.4"   "RECEIVED: EHLO smtp-cow-666"
"SMTPD" 4416    2476952 "2018-09-11 23:22:47.255"   "1.1.1.1"   "SENT: 250-mx5.bobthedestroyer.com[nl]250-SIZE 20480000[nl]250-AUTH LOGIN[nl]250 HELP"
"SMTPD" 4232    2476952 "2018-09-11 23:53:47.255"   "1.1.1.1"   "RECEIVED: MAIL FROM:<bobtheBuilder@builders.com>"
"SMTPD" 4232    2476952 "2018-09-11 23:59:47.255"   "1.1.1.1"   "SENT: 250 OK"
"SMTPD" 4416    2476952 "2018-09-11 23:11:47.270"   "1.1.1.1"   "RECEIVED: RCPT TO:<bobtheBuilder@builders.com>"
"SMTPD" 4416    2476952 "2018-09-11 23:22:47.270"   "1.1.1.1"   "SENT: 250 OK"
"SMTPD" 4308    2476952 "2018-09-11 23:55:47.270"   "1.1.1.1"   "RECEIVED: DATA"
"SMTPD" 4308    2476952 "2018-09-11 23:21:47.270"   "1.1.1.1"   "SENT: 354 OK, send."
"SMTPD" 4000    2476952 "2018-09-11 09:53:48.208"   "1.1.1.1"   "SENT: 250 Queued (0.768 seconds)"
"APPLICATION"   3100    "2018-09-11 11:53:48.208"   "SMTPDeliverer - Message 2570349: Delivering message from bobtheBuilder@builders.com to bobtheDestroyers@Destroyerrs.com . File: C:\Program Files (x86)\servers\toomanysecrets\{49E08D79-C4A5-43F1-9435-9999999999}.eml"
"APPLICATION"   3100    "2018-09-11 12:12:48.208"   "SMTPDeliverer - Message 2570349: Relaying to host bobtheBuilder@builders.com ."

这是我写的:

$Unclean_LogLines = Get-Content .\BHmailLog.txt

#$LogLines | %{"$($_.Split()[0,1,2,3,4,5,6,7,8,9,10,11,12,13 ])"}


$AppendedLogLines = [System.Collections.ArrayList]@()


#Attempts to normalise the log.... And even out the columns.So that I can grap $_[3,4] for each line.
#perhaps a simple foreach + regex would be better....

$Unclean_LogLines | foreach-object {

    $firstcolumn = ($_ -split '\s+',4)[0]
    if($firstcolumn -eq '"APPLICATION"'){
        $_ = '"APPLICATION" ' + $_ 
         $AppendedLogLines.Add($_ + "`n")

    }

    elseif($firstcolumn -eq '"TCPIP"'){
         $_ = '"TCPIP" ' + $_ 
         $AppendedLogLines.Add($_ + "`n") # minor problem here. I am not 100% normalising the log... I should make _$[2] = 4248 or something. 

    }
    else{
      $AppendedLogLines.Add($_ + "`n")

    }


}
"FINISHED NORMALISING!! "

   $AppendedLogLines| foreach-object {


    $timestamp,$null = %{"$($_.Split()[3,4])"}
     $timestamp = $timestamp.Replace('"','') # remove the last qoate....


  $_ |sort-object -property { 

    }

2 个答案:

答案 0 :(得分:2)

为了实现按时间戳的排序,您严格地不需要标准化日志

Get-Content ./BHmailLog.txt | 
  Sort-Object { [datetime] ($_ -replace '^.*?"(\d{4}-\d{2}-\d{2} [^"]+).*', '$1') }

注意:
*为简洁起见,我缩短了提取时间戳的正则表达式,使其仅与日期部分匹配,但可以使其更严格。
*如果有多个,则将按每行上遇到的 first 时间戳进行排序。

方法:

  • -replace与正则表达式和捕获组一起使用,以从每个输入行提取时间戳,
  • 通过强制转换将该字符串时间戳转换为[datetime]实例,
    • 请注意,此转换与有效的区域性无关,因为PowerShell在可能的情况下从字符串进行类型转换/解析时会使用不变区域性-并且您的时间戳记 以不变文化认可的格式。
  • 通过计算的属性({ ... })使Sort-Object执行正确的时间排序。

请注意,即使您先对日志进行了规范化,也可以使用以上的方法,但是如果您随后希望按字段 indices 定位时间戳,则: >

$AppendedLogLines | Sort-Object { [datetime] ((-split $_)[3,4] -join ' ' -replace '"') }

虽然从概念上讲这也许更清晰,更容易理解,但我不确定哪种方法效果更好。

答案 1 :(得分:0)

一个挑战。.我不能为此编写代码,但是我可以提供一些建议。.使用空格作为分隔符来分隔每一行..然后您将不得不查看每个元素(或者只是查看第3或第4个),然后查看它是否与日期/时间模式匹配。如果可以,瞧!有您的搜索元素..将其放入关键字中作为哈希值,并将整行作为数据。然后对您的哈希表进行排序。这就是我要采取的方式。

相关问题