处理异构数组的(成员)

时间:2016-03-12 13:03:39

标签: powershell

让我们创作书籍

$a = New-Object –TypeName PSObject
$a | Add-Member –MemberType NoteProperty –Name Title –Value "Journey to the West" 
$a | Add-Member –MemberType NoteProperty –Name Price –Value 12

$b = New-Object –TypeName PSObject
$b | Add-Member –MemberType NoteProperty –Name Title –Value "Faust" 
$b | Add-Member –MemberType NoteProperty –Name Author –Value "Goethe"

$array1 = $a,$b
$array2 = $b,$a

现在让我们显示这两个数组

PS D:\Developpement\Powershell> $array1

Title               Price
-----               -----
Journey to the West    12
Faust                    

PS D:\Developpement\Powershell> $array2

Title               Author
-----               ------
Faust               Goethe
Journey to the West

据我所知,这基本上意味着powershell认为是数组的属性是第一个元素的属性(事实上,这甚至不是真的,因为如果第一个元素是$null,下一个元素将被考虑)。现在这也意味着:

  • 如果你在数组上调用Get-Member,你将只获得第一个元素的成员
  • 如果您在数组上调用Convert-ToCvs,则只会导出第一个元素定义的属性的属性值

我很难理解背后的理由,这种行为让我在powershell中使用异构数组令我感到非常痛苦。

我想从各种外部源导入数据,处理它们然后将它们导出到cvs文件。项目很相似,但大多数都不可预测地错过了一些属性。有没有明显的方法可以在没有重新编程轮子的情况下在Powershell中处理它?<​​/ p>

1 个答案:

答案 0 :(得分:2)

这是必须的,因为PowerShell使用管道。当你跑前。 $array1 | Export-CSV ....,PowerShell在第一个对象到达时立即开始写入CSV文件。此时,它需要知道标题的样子,因为这是csv文件中的第一行。因此,PowerShell必须假设第一个对象的类/属性表示管道中的所有剩余对象。对于需要在输出任何对象之前设置样式/视图的Format-Table和类似命令,情况也是如此。

通常的解决方法是使用Select-Object手动指定标头。它会将所有缺少的属性添加到值为$null的所有对象。这样,所有对象都发送到ex。 Export-CSV将定义所有相同的属性。

要获取标题,您需要从数组中的所有对象接收所有唯一的属性名称。实施例

$array1 |
ForEach-Object { $_.PSObject.Properties} |
Select-Object -ExpandProperty Name -Unique

Title
Price
Author

然后,您可以在将对象发送到Select-Object -Properties Title,Price,Author之前使用Export-CSV将其指定为标题。例如:

$a = New-Object –TypeName PSObject
$a | Add-Member –MemberType NoteProperty –Name Title –Value "Journey to the West" 
$a | Add-Member –MemberType NoteProperty –Name Price –Value 12

$b = New-Object –TypeName PSObject
$b | Add-Member –MemberType NoteProperty –Name Title –Value "Faust" 
$b | Add-Member –MemberType NoteProperty –Name Author –Value "Goethe"

$array = $a,$b

$AllProperties = $array |
ForEach-Object { $_.PSObject.Properties} |
Select-Object -ExpandProperty Name -Unique

$array | Select-Object -Property $AllProperties | Export-CSV -Path "mycsv.out" -NoTypeInformation

这将创建此CSV文件:

"Title","Price","Author"
"Journey to the West","12",
"Faust",,"Goethe"

如果您有多个数组,可以将它们组合起来,如$array = $array1 + $array2