我有一个日志文件,我必须每5分钟扫描一次特定的关键字 - 特别是“订单失败”然后捕获周围的线。我有那个部分编程没有问题。其余的日志条目无关紧要。我可以使用命令:
[string] $readFile = get-content c:\test\friday.log | select-String -pattern '(order.*failed)' -context 1,7
输出:
消息:订单提交失败。
时间戳:2016年4月1日下午4:05:09
严重性:错误
消息:未授权父项的修饰符
消息:订单提交失败。
时间戳:2016年4月1日下午4:18:15
严重性:错误
消息:未授权父项的修饰符
这正是我想要的。我的问题是尝试通读上面的输出并将“Timestamp”存储到我可以操作的变量中。 第一个挑战是“时间戳”时间是以UTC时间写的,我们位于太平洋时区。 第二个挑战是我需要将“时间戳”时间与当前时间进行比较并将其存储为整数。我们只想报告当前时间5分钟内的错误。
我的当前代码只抓取了第一个“Timestamp”条目,因为我对其进行了硬编码:
[string] $readFile = get-content c:\test\friday.log | select-String -pattern '(order.*failed)' -context 1,7
$fileArray = $readFile.Split(“`n”)
[dateTime] $TrimTime = $fileArray[3].trim("Timestamp: ")
[dateTime] $currentTime = get-date
[int32] $getMinutes = (new-timespan -start $TrimTime -end $currentTime).minutes
我不知道如何遍历Get-content的输出 - 检查所有时间戳 - 我们只想报告当前时间5分钟内的错误。
答案 0 :(得分:2)
不要马上把你的比赛投射到一根绳子上。
$readFile = get-content c:\test\friday.log | select-String -pattern '(order.*failed)' -context 1,7
如果暂时保留MatchInfo
个对象,可以从aftercontexts中提取时间戳,如下所示:
$readFile | ForEach-Object {
$_.Context.AfterContext | Where-Object {
$_ -match 'timestamp: (\d{1,2}/\d{1,2}/\d{4} \d{1,2}:\d{2}:\d{2} [ap]m)'
} | ForEach-Object {
$timestring = $matches[1]
}
}
使用ParseExact()
方法将匹配的子字符串转换为DateTime
值:
$fmt = 'M\/d\/yyyy h:mm:ss ttK'
$culture = [Globalization.CultureInfo]::InvariantCulture
$timestamp = [DateTime]::ParseExact("${timestring}Z", $fmt, $culture)
附加到Z
的{{1}}表示UTC时区,格式字符串中的尾随$timestring
使方法可以识别它。结果会自动转换为您当地的时间。如果您需要UTC时间:将K
附加到方法调用。