gpt4 book ai didi

list - 如何创建输出列表(不是表格)的对象

转载 作者:行者123 更新时间:2023-12-04 23:06:34 25 4
gpt4 key购买 nike

这是另一个问题的衍生,位于此处:
Formatting an Object as a neatly looking list
我认为,论点的基础是错误的,因为我们之后没有处理对象的格式。这仅适用于控制台显示的外观,但在您操作包含对象的变量时,它可能会影响对象的完整性。

我需要的是创建一个本质上输出列表(而不是表格)的对象。我知道这是可能的,因为我已经测试了许多我没有编写的函数,并且创建的对象实际上是列表。无需使用格式列表来扭曲或塑造已经存在的内容。我只是无法弄清楚为什么有时输出是列表或表格。我不确定魔法在哪里。但是我知道当我运行时 $Host在我运行包含创建对象的变量之前,我得到了 Host 生成的对象,它是一个列表,然后将对象塑造成一个通常会显示为表格的列表。当然,这可能会给出我想要的结果,但我不想显示主机信息。那么有什么办法解决这个问题,我希望有人能解释一下。

最佳答案

PowerShell 在向用户呈现数据/对象时会执行一些默认格式设置。通常,对象最多具有 4 个属性时以表格形式显示,当它们具有 4 个以上属性时,则以列表形式显示。

如果连续输出多个内容,PowerShell 会将格式(列表/表格)从第一个对象应用到所有后续对象。我不知道这种行为背后的确切原因,但大概是为了使输出更加一致。

演示:

PS C:\> $o1 = New-Object -Type PSObject -Property @{a=1;b=2;c=3;d=4;e=5}PS C:\> $o2 = New-Object -Type PSObject -Property @{x='foo';y='bar'}PS C:\> $o1c : 3e : 5d : 4b : 2a : 1PS C:\> $o2y                                    x-                                    -bar                                  fooPS C:\> $o1; $o2c : 3e : 5d : 4b : 2a : 1y : barx : foo

Beware, however, that relying on this behavior might lead to undesired results if you output objects in the wrong order:

PS C:\> $o2; $o1y                                    x-                                    -bar                                  foo         # ← properties of $o2                                                 # ← empty line for $o1!

$o1 appears as a blank line in the above output, because outputting $o2 first establishes tabular output format with the columns y and x, but $o1 doesn't have these properties. Missing properties are displayed as blank values in tabular output, whereas additional properties are omitted from the output. There are also cases where you might get the output from the second object/list in list form (run for instance Get-Process; Get-ChildItem in a PowerShell console).

You can force subsequent objects or object arrays to be displayed as separate tables (or lists) by piping them through the Format-Table (or Format-List) cmdlet:

PS C:\> $o2; $o1 | Format-Tabley                                    x-                                    -bar                                  foo              c            e            d            b            a              -            -            -            -            -              3            5            4            2            1

You can also force PowerShell to display each variable individually by piping them through (for instance) Out-Default:

PS C:\> $o2 | Out-Default; $o1 | Out-Defaulty   x-   -bar fooc : 3e : 5d : 4b : 2a : 1

Note, however, that this writes to the console, so the resulting output can't be captured, redirected, or pipelined anymore. Use this only if you want to display something to a user.

For additional information about PowerShell output formatting see here.


There are ways to change the default behavior of how an object is displayed, but unfortunately they're not exactly straightforward. For one thing you can define a default display property set to have PowerShell display not all properties, but just a particular subset.

PS C:\> $props = 'c', 'd'PS C:\> $default = New-Object Management.Automation.PSPropertySet('DefaultDisplayPropertySet',[string[]]$props)PS C:\> $members = [Management.Automation.PSMemberInfo[]]@($default)PS C:\> $o1 | Add-Member MemberSet PSStandardMembers $membersPS C:\> $o1                c                    d                -                    -                3                    4

You can still get all properties displayed by using Format-List *:

PS C:\> $o1 | Format-List *c : 3e : 5d : 4b : 2a : 1

Defining the default display property set doesn't allow you to define the output format though. To do that you probably need to write a custom formatting file. For that to work you probably also need to define a custom type for your objects.

$formatFile = "$HOME\Documents\WindowsPowerShell\Your.Format.ps1xml"
$typeFile = "$HOME\Documents\WindowsPowerShell\Your.Type.ps1xml"

@'
<?xml version="1.0" encoding="utf-8" ?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Default</Name>
<ViewSelectedBy>
<TypeName>Foo.Bar</TypeName>
</ViewSelectedBy>
<ListControl>
...
</ListControl>
</View>
</ViewDefinitions>
</Configuration>
'@ | Set-Content $formatFile
Update-FormatData -AppendPath $formatFile

@'
<?xml version="1.0" encoding="utf-8" ?>
<Types>
<Type>
<Name>Foo.Bar</Name>
<Members>
...
</Members>
</Type>
</Types>
'@ | Set-Content $typeFile
Update-TypeData -AppendPath $typeFile

$o2.PSTypeNames.Insert(0, 'Foo.Bar')

杰弗里希克斯写了一个 article series on the subject您可能想阅读的内容。

综上所述,除非您有非常令人信服的理由,否则我不建议您走这条路。我之前尝试过解释,但是 @TesselatingHeckler说得比我简明得多,所以我要引用他的话:

PowerShell is not bash, it has a separation of content and presentation, like HTML and CSS have.



您通常希望在 PowerShell 中做的是将数据保存在对象中,并使这些对象的属性包含“原始”(即未格式化)数据。这为您处理数据提供了最大的灵活性。格式化数据通常只会碍手碍脚,因为它会迫使您再次解析/转换数据。仅在需要向用户显示数据时才格式化数据,并使用 Format-* cmdlet 这样做。如果您的输出用于进一步处理:首先不要打扰格式化它。留给用户他想如何显示数据。

关于list - 如何创建输出列表(不是表格)的对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40335091/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com