Powershell - 具有多个属性的Group-Object PSObject

时间:2018-04-07 01:11:08

标签: powershell

我正在尝试使用类似于

的PSObject数组
 @{BakId=27; Name=DB_A; Lsn=123; File=A_01; Size=987}
 @{BakId=28; Name=DB_B; Lsn=456; File=B_01; Size=876}
 @{BakId=28; Name=DB_B; Lsn=456; File=B_02; Size=765}
 @{BakId=28; Name=DB_B; Lsn=456; File=B_03; Size=654}

创建一个新的分组对象,删除多余的标题信息。

 BakId  Lsn  Name  Files
 27     123  DB_A  {@{File=A_01.bak;Size=777}}
 28     456  DB_B  {@{File=B_01.bak;Size=888}, @{File=B_02.bak;Size=999}, ...}

我尝试使用group-object但只能让它适用于一个属性。 (所有分组的属性都作为逗号分隔值的字符串进入Group.Name。)

这是我提出的最好的,但感觉很讨厌。

$list | Group-Object -Property BakId | % {
   $BakId = $_.Name
   $Lsn   = $_.Group[0].Lsn  # <--- is there a better way than this?
   $Name  = $_.Group[0].Name # <--- Ditto
   $Files = $_.Group | Select-Object -Property SequenceNumber, Size
   Write-Output (New-Object -TypeName PSObject -Property @{ BakId=$BakId;Files = $Files })
}

有更好的方法吗?

由于

1 个答案:

答案 0 :(得分:1)

您可以使用带有计算属性的单个Select-Object调用来简化构造输出对象的方法,并依赖于分组属性的顺序,通过{{1}访问其特定于组的值收集:

.Values

注意:

  • $list | Group-Object -Property BakId, Lsn, Name | Select-Object @{n='BakId'; e={ $_.Values[0] }}, @{n='Lsn'; e={ $_.Values[1] }}, @{n='Name'; e={ $_.Values[2] }}, @{n='Files'; e={ $_.Group | Select-Object File, Size }} 代替你$_.Values[<ndx>];请注意,后者只对实际的分组属性有意义,因为其他任何属性在整个组中都不一致。

  • $_.Group[0].<name>.Values实例)输出的每个组对象上的[System.Collections.ArrayList]集合(Group-Object)包含该组的共享分组属性值as-is (原始类型),按指定的顺序。
    相比之下,属性[Microsoft.PowerShell.Commands.GroupInfo]包含所有分组属性值的字符串组合:包含逗号分隔列表的字符串。
    很遗憾,Get-Help Group-Object目前缺少此类详细信息。

如果您想避免重复分组属性(例如,准备编写函数包装器; PSv3 +):

.Name