【问题标题】:PowerShell write-output missing information - prints only 1st object [duplicate]PowerShell 写入输出缺少信息 - 仅打印第一个对象 [重复]
【发布时间】:2013-08-04 00:31:01
【问题描述】:

1.ps1 创建并打印了 2 个对象。但只有一个出现在输出中。 这两个对象都出现在以下情况:
(1) 使用 Format-List
完成写输出 (2) object1 有超过 4 个属性(因此它会自动垂直格式化)
试图了解这种行为背后的原因。

PS C:\> cat .\1.ps1
$object1 = New-Object PSObject
$object1 | add-member NoteProperty -name pn1 -value pv1
$object1 | add-member NoteProperty -name pn2 -value pv2
$object1 | add-member NoteProperty -name pn3 -value pv3
write-output $object1

$object2 = New-Object PSObject
$object2 | add-member NoteProperty -name npn1 -value npv1
$object2 | add-member NoteProperty -name npn2 -value npv2
$object2 | add-member NoteProperty -name npn3 -value npv3
$object2 | add-member NoteProperty -name npn4 -value npv4
$object2 | add-member NoteProperty -name npn5 -value npv5
$object2 | add-member NoteProperty -name npn6 -value npv6
write-output $object2
PS C:\>
PS C:\> .\1.ps1

pn1                                     pn2                                     pn3
---                                     ---                                     ---
pv1                                     pv2                                     pv3


PS C:\>

【问题讨论】:

  • 你想看什么?
  • @StanleyDeBoer 显然是第二个对象。
  • 我明白了,对我来说,期望Format-Table 中的列发生变化并不明显。

标签: c# powershell powershell-2.0


【解决方案1】:

我认为这与Format-Table 的工作方式有关。我认为默认情况下 PowerShell 将选择 Format-TableFormat-List 在控制台上显示对象,我不确定如何做出决定,但显然选择了 Format-Table

Format-Table 通过获取第一个对象并从中选择属性来工作。对于第一个对象之后的任何对象,它只会填充第一个对象的属性列。

你可以试试

 .\1.ps1 | % { $_ | ft }

看看这是否能满足您的需求。

【讨论】:

  • 5 使用格式列表。但我想知道,为什么他们会愚蠢到不知道第一个和第二个写入输出具有不同的 property_names - 所以它们可能/是不同类型的对象。
  • 因为大多数时候命令一次输出一种类型的对象(我想不出任何一次输出超过一种类型的对象的内置命令),所以你是谈论一个边缘案例。边缘情况的处理方式通常与您可能期望的不同,因为在一种情况下的正确行为可能在另一种情况下是错误的行为。
  • 啊!! - 从脚本运行时,它们可能不会混合格式。所以在这里,object 1 默认是 Format-Table (5 props)。如果 cmdlet 在 shell 上运行,则 1 为 Format-Table,2 为 Format-List。我希望从脚本运行时也有相同的行为
  • 不,这不应该是一个边缘情况。我有两个单独的写输出语句。不在一个写输出中打印两个对象
  • 您使用的是Write-Output 而不是Write-Host。第一个写入管道,第二个写入控制台
【解决方案2】:

如果您只是想显示信息,您应该使用Write-Host 而不是Write-Output。当您在管道中发送数据时,您希望使用Write-Output,并且不应该用于简单地显示数据。

这是一个给出更深入答案的帖子:Which should I use: "Write-Host", "Write-Output", or "[console]::WriteLine"?

来自链接:

当您想在管道中发送数据但不一定想在屏幕上显示时,应该使用 Write-Output。如果没有其他东西首先使用它,管道最终会将其写入默认值。当你想要做相反的事情时,应该使用 Write-Host。 [console]::WriteLine 本质上是 Write-Host 在幕后所做的。

【讨论】:

  • 是的,这解释了这种行为。好吧,我遇到这种情况的真实用例 - 我们实际上需要将它流水线化,以便其他 cmdlet 可以使用通过管道传递的对象的属性/值。在我看来,从客户的角度来看,write-host 中的输出格式在视觉上并不令人愉悦。
  • 您仍然可以格式化Write-Host 以使其在视觉上更令人愉悦:)
【解决方案3】:

我无法解释这种行为,但您可以通过对第一个输出使用显式格式化程序来缓解它,例如:

Write-Output $object1 | Format-Table

在没有显式格式化的情况下,PowerShell 会记住隐式应用的表格式并忽略与此格式不匹配的输出。例如,如果您在脚本末尾添加另一个 Write-Output $object1

$object1 = New-Object PSObject
...
write-output $object1

$object2 = New-Object PSObject
...
write-output $object2
write-output $object1

你会得到这个输出:

PS C:\> .\test.ps1

pn1                                 pn2                                 pn3
---                                 ---                                 ---
pv1                                 pv2                                 pv3

pv1                                 pv2                                 pv3

Wat?!O_o

为什么有人会认为这是一个好主意,我无法理解。

【讨论】:

  • 是的,正如我在原始问题中提到的那样,格式列表有效。只是想了解为什么没有它写入控制台如此困难。如果在下一个对象中没有找到相同的道具名称,那么他们为什么不打印第二个对象的属性,值呢?
  • 可能是因为它的属性集与第一个对象不同。如果您创建另一个具有与$object1 相同的属性集的对象(即相同的名称,但不同的值),它将很好地显示。
  • 这是否证明完全跳过该对象是合理的?理想情况下,我会期望 ob1 的 prop/val 被打印出来……然后是 obj2 的 prop/val ……而不是尝试将 obj2 与 obj1 的属性结合起来。因为它们只是不匹配 - 所以它是一个不同的对象。
  • 我会说这是大多数人所期望的。而且我不记得提供任何理由。我也不打算这样做。
猜你喜欢
  • 2017-03-08
  • 2012-01-02
  • 2022-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
  • 2020-06-30
相关资源
最近更新 更多