我如何 select 某些哈希表值但在 powershell 脚本中在线更改其他值
How do I select certain hashtable values but change others in-line in a powershell script
使用管道或其他类型的内联表示法,我想 "select" 散列中的某些值 table 直接到结果,同时更改或设置其他值。
哈希Table
我从散列 table 开始(坦率地说,它像对象一样使用),如下所示:
>$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
如果我没有need/want它是内联的,我只是设置Result
的值:
$hash.Result = "good"
对于内联解决方案,我总是可以像这样使用 Foreach-Object
:
$hash | Foreach-Object {@{System=$_.System;Job=$_.Job;Result="Good"}}
或者直接在子表达式中引用 $hash:
${@{System=$hash.System;Job=$hash.Job;Result="Good"}}
然而,当我只处理一个散列 table 时使用 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 有一些相似的方面(以命名方式包含其他东西的东西),但是据我所知,它们是不兼容的——有没有更接近 Select-Object
的替代方法?我要在这里做什么?
要解析单值对象,请使用:
$hash = @{}
$hash.Add("System",$obj.System)
$hash.Add("Job"=$obj.job)
$hash.Add("Result"="Good")
如果您需要更多对象 - 迭代它们 foreach($o in $obj){$hash.Add()}
,但在循环之前声明 $hash。
当您使用 Select-Object
并添加一个不存在的列 (属性) 时,您实际上是在创建一个新的 [PSObject]
来包装原始列。您可以明确地执行此操作并使用 [hashtable]
以两种方式启动其属性:
$obj = [PSCustomObject]$hash
或
$obj = New-Object PSObject -Property $hash
从那里,您可以像往常一样使用 Select-Object
。您也可以先操作哈希以获得所需的属性,然后转换为对象并跳过 Select-Object
.
严格要求将其作为单行程序,事先没有设置代码并且不修改源哈希,这样的事情可以完成这项工作:
($hash + @{ 'Result' = 'Good' }).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}
如果您要定期添加一些东西 Result = Good
,保存您的小扩展位可能会很方便:
$good = @{ 'Result' = 'Good' }
然后你的一行变成:
($hash + $good).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}
编辑: 正如您在下面的评论中指出的那样,如果 Result
存在于散列中,则单行代码将会消失。这个版本有点 safer/more 明确,更直接地映射到你在 PSObjects 上用 Select-Object
描述的精神:
(($hash).GetEnumerator() | ? {$_.Key -in 'System','Job'}) + @{'Result' = 'Good'}
仍然不是世界上最漂亮的东西,但它完成了工作。
如果您只需要在哈希中添加或更新一个键 table:
$hash.Result += 'Good'
如果 Result 键存在,它的值将被设置为 'Good'。如果不存在,将添加该值。
使用管道或其他类型的内联表示法,我想 "select" 散列中的某些值 table 直接到结果,同时更改或设置其他值。
哈希Table
我从散列 table 开始(坦率地说,它像对象一样使用),如下所示:
>$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
如果我没有need/want它是内联的,我只是设置Result
的值:
$hash.Result = "good"
对于内联解决方案,我总是可以像这样使用 Foreach-Object
:
$hash | Foreach-Object {@{System=$_.System;Job=$_.Job;Result="Good"}}
或者直接在子表达式中引用 $hash:
${@{System=$hash.System;Job=$hash.Job;Result="Good"}}
然而,当我只处理一个散列 table 时使用 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 有一些相似的方面(以命名方式包含其他东西的东西),但是据我所知,它们是不兼容的——有没有更接近 Select-Object
的替代方法?我要在这里做什么?
要解析单值对象,请使用:
$hash = @{}
$hash.Add("System",$obj.System)
$hash.Add("Job"=$obj.job)
$hash.Add("Result"="Good")
如果您需要更多对象 - 迭代它们 foreach($o in $obj){$hash.Add()}
,但在循环之前声明 $hash。
当您使用 Select-Object
并添加一个不存在的列 (属性) 时,您实际上是在创建一个新的 [PSObject]
来包装原始列。您可以明确地执行此操作并使用 [hashtable]
以两种方式启动其属性:
$obj = [PSCustomObject]$hash
或
$obj = New-Object PSObject -Property $hash
从那里,您可以像往常一样使用 Select-Object
。您也可以先操作哈希以获得所需的属性,然后转换为对象并跳过 Select-Object
.
严格要求将其作为单行程序,事先没有设置代码并且不修改源哈希,这样的事情可以完成这项工作:
($hash + @{ 'Result' = 'Good' }).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}
如果您要定期添加一些东西 Result = Good
,保存您的小扩展位可能会很方便:
$good = @{ 'Result' = 'Good' }
然后你的一行变成:
($hash + $good).GetEnumerator() | ? {$_.Key -in 'Result','System','Job'}
编辑: 正如您在下面的评论中指出的那样,如果 Result
存在于散列中,则单行代码将会消失。这个版本有点 safer/more 明确,更直接地映射到你在 PSObjects 上用 Select-Object
描述的精神:
(($hash).GetEnumerator() | ? {$_.Key -in 'System','Job'}) + @{'Result' = 'Good'}
仍然不是世界上最漂亮的东西,但它完成了工作。
如果您只需要在哈希中添加或更新一个键 table:
$hash.Result += 'Good'
如果 Result 键存在,它的值将被设置为 'Good'。如果不存在,将添加该值。