在撰写本文时,有两个答案(一个来自 Shay Levy 和一个来自 jon Z)都非常接近,但两者都不完全正确——尽管 Shay 的答案已经被接受(!)。原因如下:
Shay 的代码问题
Shay 的回答过于字面,基于一个不准确的要求,该要求指定创建一个“可能包含类似条目的哈希表”:
@(Key=Mailcomp,Value=BL_2.1.0.9.5179)
@(Key=OfficeComp, Value=BL_2.1.0.17.6972)
但是,如果要使用 PowerShell 语法,则说明不正确。现实中的需求应该是这样的:
@{Mailcomp=BL_2.1.0.9.5179}
@{OfficeComp=BL_2.1.0.17.6972}
也就是说,第一行指定了Mailcomp的哈希key和BL_2.1.0.9.5179的哈希value。这个修改版的 Shay 代码准确地提供了:
$hash = @{}
Get-Content $BaselineFile |
Foreach-Object {
if ($_ -match '^\(([^@]+).+\)\s([^@]+)')
{
$hash[$matches[1]]=$matches[2]
}
}
这是输出:
Name Value
---- -----
Mailcomp BL_2.1.0.9.5179
OfficeComp BL_2.1.0.17.6972
这更容易使用,因为我现在可以访问 $hash["Mailcomp"] 或 $hash["OfficeComp"] 来检索它们各自的值。
Shay 代码的第二个问题是哈希条目创建本身 (@{ key=$matches[1]; value=$matches[2] })。该语句为每次迭代(即输入的每一行)创建一个单独的“迷你”哈希表。由于在他的代码中合并了隐式 Write-Output,它似乎 只能产生合理的输出。为了证明这一点——并将苹果与苹果进行比较——使用我上面的代码并将条件替换为等效于 Shay 的代码:
if ($_ -match '^\(([^@]+).+\)\s([^@]+)')
{
@{ $matches[1]=$matches[2] }
}
您会发现$hash["Mailcomp"] 确实没有返回预期的BL_2.1.0.9.5179。
Jon 的代码问题
我喜欢 jon Z 的回答;我真的。真的。但它让我想起了一个伟大的老笑话assume we have a can opener... 这是一个非常好的解决方案当且仅当输入适合一个简单的分隔符。这里不是这种情况——需要一个正则表达式(或其他机制)来按摩输入。平心而论,Jon 明确指出他正在假设一些预处理。 `纳夫说。