我正在开始使用 powershell,但我现在的知识还很贫乏。 我有这个 .log 文件,如下所示:
18.7.2017 12:59:15 Starting thread: KEYWORD1
18.7.2017 12:59:33 Thread finished; ... KEYWORD1
18.7.2017 13:32:19 Starting thread: KEYWORD2
18.7.2017 13:34:8 Thread finished;... KEYWORD2
我现在想知道,是否每个启动的线程也都已完成。 如果有未完成的线程,我想将时间戳与当前时间进行比较。
我认为哈希表可以解决问题,这就是我想到的:
foreach($line in Get-Content $sourceDirectory)
{
if($line -like "*Starting thread*")
{
$arrStart = $line -split ' '
$startThreads=$arrStart[$arrStart.Length-1]
$hashmap1 = @{$arrEnd[$arrEnd.Length-1] = $arrEnd[1]}
}
if($line -like "*Thread finished*")
{
$arrEnd = $line -split ' '
$hashmap2 = @{$arrEnd[$arrEnd.Length-1] = $arrEnd[1]}
$endThreads=($arrEnd[1]+" "+$arrEnd[$arrEnd.Length-1])
}
}
现在如何比较这两个 HashMap ?
最佳答案
JPBlanc建议对问题评论中的记录进行分组,并且 the Group-Object
cmdlet确实提供了一个概念上优雅的解决方案:
注意:假设如果给定关键字只有一个条目,则它始终是起始条目。
Select-String 'Starting thread:|Thread finished;' file.log |
Group-Object { (-split $_)[-1] } | Where-Object { $_.Count % 2 -eq 1 }
Select-String
call 使用 regex(正则表达式)仅提取感兴趣的行(线程开始、线程结束)Group-Object
调用按最后一个 ([-1]
) 空格分隔的标记 (-split .. .
) 每行 ($_
),即关键字。Where-Object
然后仅返回那些具有奇数个条目的结果,即那些不成对的条目,代表已启动但未完成的线程。
这会产生如下内容:
Count Name Group
----- ---- -----
1 KEYWORD3 {/Users/jdoe/file.log:5:28.8.2018 08:59:16 Starting thread: KEYWORD3}
这可能不是您想要的格式,但鉴于输出是对象(正如 PowerShell 中的典型情况),您可以轻松地以编程方式根据您的喜好处理它们。
从技术上讲,上述命令输出 [Microsoft.PowerShell.Commands.GroupInfo]
在本例中 .Group
属性包含 [Microsoft.PowerShell.Commands.MatchInfo]
的实例实例,由 Select-String
输出。
以下代码扩展了上面的代码以生成自定义输出,报告自每个未完成的线程启动以来已经过去了多少时间:
$now = Get-Date
Select-String 'Starting thread:|Thread finished;' file.log |
Group-Object { (-split $_)[-1] } | Where-Object { $_.Count % 2 -eq 1 } | ForEach-Object {
foreach ($matchInfo in $_.Group) { # loop over started-only lines
$tokens = -split $matchInfo.Line # split into tokens by whitespace
$date, $time = $tokens[0..1] # extract date and time (first 2 tokens)
$keyword = $tokens[-1] # extract keyword (last token)
# Parse date+time into a [datetime] instance.
# Note: Depending on the current culture, [datetime]::Parse("$date $time") may do.
$start = [datetime]::ParseExact("$date $time", 'd\.M\.yyyy HH:mm:ss', [cultureinfo]::InvariantCulture)
# Custom output string containing how long ago the thread was started:
"Thread $keyword hasn't finished yet; time elapsed since it started: " +
($now - $start).ToString('g')
}
}
这会产生如下内容:
Thread KEYWORD3 hasn't finished yet; time elapsed since it started: 2:03:35.347563
2:03:35.347563
(2 小时,3 分钟,...)是 [TimeSpan]
的字符串表示形式实例是减去两个时间点([datetime]
实例)的结果。
关于powershell - 如何使用 Powershell 将哈希表与另一个哈希表进行比较?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52058355/