Powershell中Export-Csv中使用和不使用管道的区别

Mag*_*ism 4 csv powershell

这可能更像是"PowerShell如何处理变量和管道"而不是特定的程序问题,但由于它看起来像是奇怪的行为(对我来说),我以为我会在这里发布它.

我在使用PowerShell将变量导出到CSV时遇到了一些困难,发现这个Stack问题对我有很大帮助.然而,当摆弄输出时,我得到了两个不同的结果,这取决于我调用Export-CSV函数的方式.

我有一个自定义的PS对象,看起来大致如下:

Account      Partner     ProjectName     ProjectPhase
1            A           Test            Start
2            B           Test2           Start
3            A           Test4           End
4            C           Test3           Middle
....
Run Code Online (Sandbox Code Playgroud)

当我使用以下行时,它正确输出CSV文件:

$csvBody | Export-Csv -Path "$targetPath\$fileName" -Encoding Unicode -NoTypeInformation
Run Code Online (Sandbox Code Playgroud)

但是,当我使用以下行时,它不会:

Export-Csv -InputObject $csvBody -Path "$targetPath\$fileName" -Encoding Unicode -NoTypeInformation
Run Code Online (Sandbox Code Playgroud)

在这种情况下,输出如下所示:Count,"Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"263,"263","263"," 1" , "System.Object的[]", "假", "真", "假"

我从其他Stack帖子中了解到输出成为$ csvBody的属性,这是一个数组.我的问题是,为什么会发生这种情况时,我没有管道对象以出口为CSV,但它不会发生时,我正在使用的管道?

Mar*_*agg 5

我认为这是因为Export-CSV编写的目的是它应该(并且会)通常通过管道处理输入.

我认为你看到的行为是因为-InputObject参数不接受数组输入.您可以从帮助页面看到:

   Export-Csv [[-Path] <String>] [[-Delimiter] <Char>] [-Append] [-Confirm] [-Encoding <String> {Unicode | UTF7 |
   UTF8 | ASCII | UTF32 | BigEndianUnicode | Default | OEM}] [-Force] -InputObject <PSObject> [-LiteralPath <String>]
   [-NoClobber] [-NoTypeInformation] [-WhatIf] [<CommonParameters>]
Run Code Online (Sandbox Code Playgroud)

<psobject>不是<psobject[]>并且因此它期望单个<psobject>输入.当它通过参数行提供时,它似乎不会展开该对象,而是为您提供一个CSV,其中包含该对象本身的默认属性(长度等).

通过管道发送对象时,它使用PROCESS接受管道输入的cmdlet 功能来展开对象并单独处理集合中的每个项目.

有人可以比我上面更好地解释这一点,或者也许可以解释为什么Export-CSV不能按照你期望的方式工作(除了 - 我认为 - 按设计).


JPB*_*anc 4

这里一切都按照设计进行,并且写得不错

在第二种方式中,#TYPE System.Object[]如果保留 TypeInformation,则输入对象是 a。

当您使用管道调用 Export-Csv 时,集合中的每个对象都会发送到 Cmdlet 的进程部分。


取一个整数的集合:

$a = 1..4
Run Code Online (Sandbox Code Playgroud)

然后尝试:

$a | Get-Member
Run Code Online (Sandbox Code Playgroud)

它给 :System.Int32

然后尝试:

Get-Member -InputObject $a
Run Code Online (Sandbox Code Playgroud)

它给 :System.Object[]

因此,在您的情况下,导出的对象是数组,这也很有用。