在PowerShell v3中,为什么将表达式的结果存储在另一个对象中?

时间:2019-04-25 14:32:37

标签: powershell

这个问题纯粹是为了增进我对PowerShell的理解。

与将管道的结果存储在变量中并在其上使用度量的情况相比,我试图了解在使用度量命令与管道进行交互时,幕后实际发生的情况。我得到了不同的对象/值。

如果我先这样做:

echo '[1,2,3,4,5]' | ConvertFrom-Json | measure

我得到:

Count    : 1
Average  : 
Sum      : 
Maximum  : 
Minimum  : 
Property : 

但是,如果我随后将结果捕获到变量中并执行:

$obj = echo '[1,2,3,4,5]' | ConvertFrom-Json
$obj | measure

我得到:

Count    : 5
Average  : 
Sum      : 
Maximum  : 
Minimum  : 
Property : 

我可以看到变量$obj的类型是System.Array

PS> $obj.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

当在管道中传递给measure命令时(我认为它是类型对象),我不知道类型。

1 个答案:

答案 0 :(得分:4)

如果您通过将Measure-Object替换为Get-Member来查看转换的实际输出,则该行为应该会更加清楚:

PS C:\> echo '[1,2,3,4,5]' | ConvertFrom-Json | Get-Member

   TypeName: System.Object[]

Name           MemberType            Definition
----           ----------            ----------
Count          AliasProperty         Count = Length
...
PS C:\> $obj = echo '[1,2,3,4,5]' | ConvertFrom-Json
PS C:\> $obj | Get-Member

   TypeName: System.Int32

Name        MemberType Definition
----        ---------- ----------
CompareTo   Method     int CompareTo(System.Object value), int Compa...
...

基本上,正在发生的事情是ConvertTo-Json产生了一个数组对象,该数组对象被下一个cmdlet照原样使用。因此Measure-Object仅计入一项(数组)。

通过在将变量传递到下一个cmdlet之前将其捕获到变量中,可以展开数组,以便Measure-Object看到(并计数)数组的 elements

通过将转换放在分组表达式中,可以将捕获转换输出到变量中,从而获得与之相同的结果:

PS C:\> $obj = echo '[1,2,3,4,5]' | ConvertFrom-Json
PS C:\> $obj | Measure-Object

Count    : 5
Average  :
Sum      :
Maximum  :
Minimum  :
Property :

PS C:\> (echo '[1,2,3,4,5]' | ConvertFrom-Json) | Measure-Object

Count    : 5
Average  :
Sum      :
Maximum  :
Minimum  :
Property :