管道完整的数组对象而不是一次一个数组项? [英] Pipe complete array-objects instead of array items one at a time?

查看:24
本文介绍了管道完整的数组对象而不是一次一个数组项?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题 - 一般描述
正如在 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-ObjectSelect-ObjectWrite-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 ?



脚注

  1. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆