Powershell 处理异构阵列的(成员)

Powershell 处理异构阵列的(成员),powershell,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 –MemberTy

让我们创造书籍

$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

因此,据我所知,这基本上意味着PosiSek认为数组的属性是其<强>第一< /强>元素的属性(事实上,这甚至不是真的,因为如果第一个元素是“代码> $null ”,下一个将被考虑)。这也意味着:

  • 如果在数组上调用
    Get Member
    ,则只会获取第一个元素的成员
  • 如果在数组上调用
    Convert-ToCvs
    ,则仅导出由第一个元素定义的属性的属性值
我几乎不理解这背后的道理,这种行为让我在powershell中使用异构阵列感到非常痛苦


我想从各种外部源导入数据,处理它们,然后将它们导出到cvs文件。项目是相似的,但它们中的大多数都不可预测地遗漏了一些属性。在Powershell中是否有任何明显的方法可以在不重新编程控制盘的情况下处理此问题?

这是必须的方式,因为Powershell使用管道。运行ex.
$array1 |导出CSV…
时,PowerShell会在第一个对象到达后立即开始写入CSV文件。此时,它需要知道头是什么样子,因为这是csv文件中的第一行。因此,PowerShell必须假设第一个对象的类/属性代表管道中的所有剩余对象。这同样适用于在输出任何对象之前需要设置样式/视图的
格式表
和类似命令

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

要获取标头,需要从数组中的所有对象接收所有唯一的属性名称。前

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

Title
Price
Author
然后,在将对象发送到导出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
$array | select($array |%{$.PSObject.Properties}select-exp name-u)| ConvertTo Csv
获取成员显示数组中每种不同类型的第一个对象的成员集<代码>$a.pstypenames.Insert(0,“BookForSale”)$a1 | gm