2

使用管道或其他类型的内联表示法,我想在哈希表中“选择”某些值直接到结果,同时更改或设置其他值。

哈希表

我从一个哈希表开始(坦率地说,它就像一个对象一样使用),如下所示:

>$hash

Name               Value
----               -----
System             server-1
Job                Microsoft.PowerShell.Commands.PSWmiJob
Result

有没有办法使用 Select-Object cmdlet(或类似的东西)来设置某些属性的值并传递其他属性?我想结束这个:

>$hash

Name               Value
----               -----
System             server-1
Job                Microsoft.PowerShell.Commands.PSWmiJob
Result             Good

如果我不需要/不希望它是内联的,我只需设置以下值Result

$hash.Result = "good"

对于内联解决方案,我总是可以这样使用Foreach-Object

$hash | Foreach-Object {@{System=$_.System;Job=$_.Job;Result="Good"}}

或者直接在子表达式中引用 $hash:

${@{System=$hash.System;Job=$hash.Job;Result="Good"}}

但是,当我只处理一个哈希表时使用它似乎很荒谬Foreach-Object,并且非常冗长地提及两次我只想通过的属性,然后如果我的$hash变量是$aSignificantlyLongerHashTableVariableName.

如果我使用的是 Powershell 对象...

如果我使用这样的对象:

>$obj

System        Job                                      Result
------        ---                                      ---
server-1      Microsoft.PowerShell.Commands.PSWmiJob             

我会select-object像这样使用 Cmdlet:

>$obj | Select-Object System, Job, @{Name="Result";Expression="Good"}

这将导致

>$obj

System        Job                                      Result
------        ---                                      ---
server-1      Microsoft.PowerShell.Commands.PSWmiJob   Good

Hashtable 和 PSObject 有一些相似的方面(以命名方式包含其他东西的东西),但是 AFAIK,它们是不兼容的 - 有没有更接近Select-Object我在这里尝试做的事情的替代方案?

4

4 回答 4

2

严格要求将其作为单行程序,事先没有设置代码并且不修改源哈希,这样的事情可以完成这项工作:

($hash + @{ 'Result' = 'Good' }).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}

如果你要Result = Good定期添加一些东西,保存你的小扩展位可能会很方便:

$good = @{ 'Result' = 'Good' }

然后你的单行变成:

($hash + $good).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}

编辑:Result正如您在下面的评论中指出的那样,如果存在于散列中,该单行将死亡。这个版本更安全/更明确,更直接地映射到你Select-Object在 PSObjects 上描述的精神:

(($hash).GetEnumerator() | ? {$_.Key -in 'System','Job'}) + @{'Result' = 'Good'}

仍然不是世界上最漂亮的东西,但它确实有效。

于 2016-03-03T15:43:15.540 回答
0

要解析单值对象,请使用:

$hash = @{}
$hash.Add("System",$obj.System)
$hash.Add("Job"=$obj.job)
$hash.Add("Result"="Good")

如果您需要更多对象 - 迭代它们foreach($o in $obj){$hash.Add()},但在循环之前宣布 $hash。

于 2016-03-03T15:24:25.000 回答
0

当您使用Select-Object并添加一个不存在的列(属性)时,您实际上是在创建一个[PSObject]包含原始列的新列。您可以通过[hashtable]两种方式显式执行此操作并使用 a 来启动其属性:

$obj = [PSCustomObject]$hash

或者

$obj = New-Object PSObject -Property $hash

从那里,您可以Select-Object照常使用。您还可以先操作散列以获得所需的属性,然后转换为对象并跳过Select-Object

于 2016-03-03T15:33:34.737 回答
0

如果您只需要在哈希表中添加或更新键:

$hash.Result += '好'

如果 Result 键存在,它的值将设置为“Good”。如果它不存在,它将添加该值。

于 2016-03-03T16:39:13.217 回答