问题描述
Backstory:所以我所做的是搜索所述错误的关键字,(假设它不返回空值)根据生成的最后一个错误获取日期时间戳,并使用日期作为模式重新搜索日志select-string cmdlet 中的标识符。关键是查看错误是否在存储的最后一个错误日期之后再次发生,因为日志正在被主动写入。 例如,在我的日志文件中,我有这样一行:
[2020-02-22 22:22:22,222] @ 并且出现错误时出错
好的整洁。我已经从之前获取了日期并将其存储在我的 $date 变量中,特别是:
$date = "2020-02-22 22:22:22,222"
所以现在我的下一行代码是
Get-content -path c:\test\test.txt -Tail 1800 | Select-String -pattern $date -Context 0,1000
...但它不返回任何东西。甚至没有错误。就好像它显示输出为空一样,即使我知道我的日志已经说日期戳,因为我之前解析了两行代码并将日期存储为变量。我使用了单引号、双引号和无引号,这都导致没有返回任何内容。
解决方法
如何获得准确的日期匹配
调用 [Regex]::Escape()
并且您将始终在文字上完全匹配。请参阅下面的 $date2
。
这是我的示例日志
$sample = @'
[info] Line1: stuff
[warn] Line2
[2020-02-22 22:22:22,222] @ and error has occured at error
[warn] line4
[verbose] line5: more
'@
作为一行传递会产生意想不到的结果
Select-String
需要一个字符串列表。 $Sample
当前是 1 个带有换行符的字符串。因此,如果您像这样使用它,它会返回整个字符串——即使上下文设置为 0。
$date = '2020-02-22 22:22:22,222'
# or this automatically escapes special regex chars for you:
$date2 = [Regex]::Escape('[2020-02-22 22:22:22,222]')
$sample | Select-String -Pattern $date -Context 0,0
-Context
在传递字符串/行列表时起作用
$sample -split '\r?\n' | Select-String -Pattern $date -Context 1,1
返回想要的行:
[warn] Line2
[2020-02-22 22:22:22,222] @ and error has occured at error
[warn] line4
将日志行转换为DateTime
对象
# the date format almost automatically detects it. Replacing fixes it.
$lineFromLog = '2020-02-22 22:22:22,222' -replace ',','.'
$datetime_line = [datetime]$lineFromLog
比确切日期更好的过滤
首先,新日志和regex
$sample2 = @'
[2020-02-21 22:00:22,222][info] Line1: stuff
[2020-02-22 22:04:31,113][warn] Line2
[2020-02-22 22:22:22,311] @ and error has occured at error
[2020-02-22 23:22:22,215][warn] line4
[2020-02-23 22:22:22,412][verbose] line5: more
'@
$regexLog = @'
(?x)
\[(?<DateTime>[^\]]*)\]
(?<Rest>.*)
'@
该正则表达式用于创建 PSCustomObject
$parsed = $sample2 -split '\r?\n'
| ForEach-Object {
if ($_ -match $regexLog) {
# This could be improved by using '[datetime]::ParseExact'
$datetime = try {
[datetime]($matches['Datetime'] -replace ','.')
} catch {
$datetime = $matches['DateTime']
}
$hash = @{
'Datetime' = $datetime
'Rest' = $matches['Rest']
}
[pscustomobject]$hash
}
}
您可以使用日期对象选择目标日期。这让您可以使用 greater than or equal to
运算符。您可以扩展它,以便您可以按严重性和日期进行过滤。
$targetDate = [datetime]'2/22/2020 10:22:22 PM'
$parsed | Where-Object DateTime -GE $targetDate
# and the second one limits the count
$parsed | Where-Object DateTime -GE $targetDate | Select-Object -First 2