管道完整的数组对象而不是一次一个数组项? [英] Pipe complete array-objects instead of array items one at a time?
问题描述
问题 - 一般描述
正如在 about_pipelines(帮助管道
)powershell 的帮助中所见在管道中一次发送一个对象¹.所以 Get-Process -Name 记事本 |Stop-Process
每次向管道发送一个进程.
The problem - Generic description
As can be seen in help for about_pipelines (help pipeline
) powershell sends objects one at the time down the pipeline¹. So Get-Process -Name notepad | Stop-Process
sends one process at the time down the pipe.
假设我们有一个无法以任何方式修改或更改的第 3 方 CmdLet (Do-SomeStuff).如果 Do-SomeStuff 传递的是字符串数组,或者传递的是单个字符串对象,则它的表现会有所不同.
Lets say we have a 3rd party CmdLet (Do-SomeStuff) that can't be modified or changed in any way. Do-SomeStuff perform different if it is passed an array of strings or if it is passed a single string object.
Do-SomeStuff 只是一个例子,它可以代替 ForEach-Object
、Select-Object
、Write-Host
>(或任何其他接受管道输入的 CmdLet)
Do-SomeStuff is just an example, it could be substituted for ForEach-Object
, Select-Object
, Write-Host
(or any other CmdLet accepting pipeline input)
在本例中,Do-SomeStuff 将同时处理数组中的单个项目.
Do-SomeStuff will in this example process the individual items in the array one at the time.
$theArray = @("A", "B", "C")
$theArray | Do-SomeStuff
如果我们想将完整的数组作为一个对象发送给 Do-SomeStuff,可以尝试这样的操作
If we want to send the complete array as one object to Do-SomeStuff one might try something like this
@($theArray) | Do-SomeStuff
但它不会产生预期的结果,因为 PowerShell忽略"了新的单项数组.
But it does not produce the expected result since PowerShell "ignores" the new single-item-array.
那么,您如何强制"$theArray
作为单个数组对象而不是当时的内容项在管道中传递?
So, how do you "force" $theArray
to be passed down the pipe as a single array-object instead of the content items one at the time?
问题——实际例子
如下所示,Write-Host
的输出是不同的,如果传递的是一个数组,或者如果它同时传递了数组中的单个项.
The problem - practical example
As shown below the output of Write-Host
is different if passed an array or if it passed the individual items in the array one at the time.
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
相同的输出?
How do you do to get $theArray | foreach{Write-Host $_}
to produce the same output as Write-Host $theArray
?
脚注
- Powershell 中的管道处理
一个普通的字符串数组
PS C:\> @("A", "B", "C").GetType().FullName
System.Object[]
一个普通的字符串数组通过管道传输到 Foreach-Object
A normal array of strings piped to Foreach-Object
PS C:\> @("A", "B", "C") | foreach{$_.GetType().FullName}
System.String
System.String
System.String
数组中的每个字符串由 ForEach-Object CmdLet 一次处理一个.
Each string in the array is processed one at the time by the ForEach-Object CmdLet.
数组数组,其中内部"数组是字符串数组.
An array of arrays, where the "inner" arrays are arrays of strings.
PS C:\> @(@("A", "B", "C"), @("D", "E", "F"), @("G", "H", "I")) | foreach{$_.GetType().FullName}
System.Object[]
System.Object[]
System.Object[]
数组中的每个数组都由 ForEach-Object CmdLet 一次处理一个,并且来自输入的每个子数组的内容作为一个对象处理,即使它是一个数组.
Each array in the array is processed one at the time by the ForEach-Object CmdLet, and the content of each sub-array from the input is handled as one object even though it is an array.
推荐答案
简答:使用一元数组运算符,
:
,$theArray | foreach{Write-Host $_}
长答案:关于 @()
运算符,您应该了解一件事:它始终将其内容解释为语句,即使内容只是一个表达式.考虑这个代码:
Long answer: there is one thing you should understand about @()
operator: it always interpret its content as statement, even if content is just an expression. Consider this code:
$a='A','B','C'
$b=@($a;)
$c=@($b;)
我在这里添加了明确的语句结束标记 ;
,尽管 PowerShell 允许省略它.$a
是三个元素的数组.$a;
语句的结果是什么?$a
是一个集合,因此应该枚举集合并且每个单独的项目都应该通过管道传递.所以 $a;
语句的结果是写入管道的三个元素.@($a;)
看到三个元素,而不是原始数组,并从它们创建数组,所以 $b
是三个元素的数组.同样的方式 $c
是相同的三个元素的数组.因此,当您编写 @($collection)
时,您创建了数组,即复制 $collection
的元素,而不是单个元素的数组.
I add explicit end of statement mark ;
here, although PowerShell allows to omit it. $a
is array of three elements. What result of $a;
statement? $a
is a collection, so collection should be enumerated and each individual item should be passed by pipeline. So result of $a;
statement is three elements written to pipeline. @($a;)
see that three elements, but not the original array, and create array from them, so $b
is array of three elements. Same way $c
is array of same three elements. So when you write @($collection)
you create array, that copy elements of $collection
, instead of array of single element.
这篇关于管道完整的数组对象而不是一次一个数组项?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!