如何将管道中一个CmdLet的输出作为完整的数组对象发送到下一个CmdLet,而不是逐个单独发送数组中的项?
问题 - 通用描述
正如在about_pipelines(帮助管道)中所示,PowerShell会逐个向下传送对象。因此,Get-Process -Name notepad | Stop-Process
会将一个进程逐个发送到管道。
假设我们有一个第三方CmdLet(Do-SomeStuff),不能以任何方式修改或更改它。如果传递一个字符串数组或传递单个字符串对象,Do-SomeStuff会执行不同的操作。
Do-SomeStuff只是一个例子,它可以替换为ForEach-Object
、Select-Object
、Write-Host
(或任何其他接受管道输入的CmdLet)
在本例中,Do-SomeStuff将逐个处理数组中的每个项。
$theArray = @("A", "B", "C")
$theArray | Do-SomeStuff
如果我们想将整个数组作为一个对象发送到Do-SomeStuff,可以尝试像这样:
@($theArray) | Do-SomeStuff
但是,由于PowerShell“忽略”新的单项数组,它并没有产生预期的结果。
那么,如何“强制”$theArray
作为单个数组对象传递到管道中,而不是一次传递一个内容项呢?
问题 - 实际示例
如下所示,如果将数组传递给Write-Host
,输出就会与逐个传递数组中的各个项时不同。
PS C:\> $theArray = @("A", "B", "C")
PS C:\> Write-Host $theArray
A B C
PS C:\> $theArray | foreach{Write-Host $_}
A
B
C
PS C:\> @($theArray) | foreach{Write-Host $_}
A
B
C
如何使$theArray | foreach{Write-Host $_}
产生与Write-Host $theArray
相同的输出?
脚注
- Powershell中的管道处理
一个普通的字符串数组
PS C:\> @("A", "B", "C").GetType().FullName
System.Object[]
将一个普通的字符串数组传递给 Foreach-Object
PS C:\> @("A", "B", "C") | foreach{$_.GetType().FullName}
System.String
System.String
System.String
ForEach-Object命令按顺序逐个处理数组中的每个字符串。
一个数组,其中包含多个数组,每个“内部”数组都是由字符串组成的数组。
PS C:\> @(@("A", "B", "C"), @("D", "E", "F"), @("G", "H", "I")) | foreach{$_.GetType().FullName}
System.Object[]
System.Object[]
System.Object[]
ForEach-Object CmdLet逐个处理数组中的每个数组,即使它是一个数组,也将输入的每个子数组的内容处理为一个对象。
@(@(@()))
获取多个数组(粗略地说)。 - Etan Reisner@()
括起来不起作用吗? - Etan Reisner"A", "B", "C" | Format-Custom -Expand CoreOnly
证明你正在将整个数组推送到Format-Custom
命令中,那么你想要什么呢? - Vincent De Smet