度量-Sum -Property不产生输出

时间:2019-05-07 19:37:58

标签: powershell

$Data = @()
foreach($i in 1..10) {
    $Data += New-Object PSObject -Property @{        
        Money = 10
    }
}

echo "-----Data-----"
$Data

echo "-----Measure-----"
$Data | Measure -Sum -Property "Money"

输出:

-----Data-----

Money
-----
   10
   10
   10
   10
   10
   10
   10
   10
   10
   10
-----Measure-----

如果运行此代码,则会看到第$Data | Measure -Sum -Property "Money"行未生成任何输出。但!如果您将第$Data行注释掉,则会得到

-----Data-----
-----Measure-----


Count    : 10
Average  : 
Sum      : 100
Maximum  : 
Minimum  : 
Property : Money

符合预期。 为什么????为什么相同的语句返回不同的结果?

3 个答案:

答案 0 :(得分:1)

请注意,只有当您将整个代码段作为单个语句运行时(例如,作为ISE中的脚本,或者复制粘贴整个代码段),才会发生这种情况。相反,如果您从PowerShell控制台单独运行每个语句行,则将获得预期的结果。

正如@PetSerAl所说,问题与格式有关。有关更多详细信息,请参见我的回答:Running Line by Line Produces Odd Result Compared to Running Lines as a Single Line with Semicolons

运行:

PS C:\> $Data = @()
>> foreach($i in 1..10) {
>>     $Data += New-Object PSObject -Property @{
>>         Money = 10
>>     }
>> }
>>
>> echo "-----Data-----"
>> $Data
>>
>> echo "-----Measure-----"
>> $Data | Measure -Sum -Property "Money"

输出:

-----Data-----

Money
-----
   10
   10
   10
   10
   10
   10
   10
   10
   10
   10
-----Measure-----

将命令链接成一个命令时, First 对象将确定整行的输出格式。因此,看看我们得到的类型:

PS C:\> $Data.GetType()

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

PS C:\> ($Data | Measure -Sum -Property "Money").GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    GenericMeasureInfo                       Microsoft.PowerShell.Commands.MeasureInfo

在此示例中,第一个对象$Data的类型为Object[],因此它将尝试以Object[]格式格式化所有其他对象。由于第二个命令输出的对象类型为GenericMeasureInfo,因此无法以相同的方式对其进行格式化。由于两种格式不兼容,因此将丢弃Measure对象信息,并且不输出。

注释掉第一个$Data语句时,仅输出Measure对象,是的,您会看到格式正确的Measure对象。

现在,让我们翻转一下:

PS C:\Temp> $Data = @()
>> foreach($i in 1..10) {
>>     $Data += New-Object PSObject -Property @{
>>         Money = 10
>>     }
>> }
>> echo "-----Measure-----"
>> $Data | Measure -Sum -Property "Money"
>>
>> echo "-----Data-----"
>> $Data

输出:

-----Measure-----


Count    : 10
Average  :
Sum      : 100
Maximum  :
Minimum  :
Property : Money

-----Data-----
Money : 10

Money : 10

Money : 10

Money : 10

Money : 10

Money : 10

Money : 10

Money : 10

Money : 10

Money : 10

这看起来很奇怪,因为$Data对象 did 这次输出了,但是没有以表格格式输出。相反,它遵循不同的格式设置规则。第一个对象的类型为GenericMeasureInfo,因此它将尝试以GenericMeasureInfo格式格式化其他所有对象。由于第二条命令输出的对象类型为Object[],因此无法以相同的方式对其进行格式化。但是在这种情况下,PowerShell并没有丢弃信息,而是认为它可以退回到以列表的形式输出$Data的输出(因此,您会看到"Money : 10")。

Out-String是另一种处理方式:

PS C:\> $Data = @()
>> foreach($i in 1..10) {
>>     $Data += New-Object PSObject -Property @{
>>         Money = 10
>>     }
>> }
>>
>> echo "-----Data-----"
>> $Data | Out-String
>>
>> echo "-----Measure-----"
>> $Data | Measure -Sum -Property "Money"
-----Data-----

Money
-----
   10
   10
   10
   10
   10
   10
   10
   10
   10
   10



-----Measure-----


Count    : 10
Average  :
Sum      : 100
Maximum  :
Minimum  :
Property : Money

Out-String在这种情况下有效,因为它将输出对象类型的格式从Object[]转换为String格式,Measure对象知道输出格式。

答案 1 :(得分:0)

正如@LotPings所说,使用Out-String代码可以按预期工作。

答案 2 :(得分:0)

这是一个常见的陷阱。格式表隐式运行,并且它不知道如何显示不同的列集。通过format-list管道脚本可以正常工作。另一个怪异的解决方法是将get-date放在脚本的开头。由于某种原因,顶部的已知对象类型(具有格式文件)使输出“更好”。您还可以对单个命令使用format-table和format-date。