List 如何创建输出列表(而不是表)的对象
这是另一个问题的衍生,位于此处: 我认为,这个论点的基础是错误的,因为我们没有在事后处理对象的格式。这仅适用于控制台显示的外观,但在操作包含对象的变量时,它可能会影响对象的完整性List 如何创建输出列表(而不是表)的对象,list,powershell,object,List,Powershell,Object,这是另一个问题的衍生,位于此处: 我认为,这个论点的基础是错误的,因为我们没有在事后处理对象的格式。这仅适用于控制台显示的外观,但在操作包含对象的变量时,它可能会影响对象的完整性 我需要的是创建一个内在输出列表(而不是表)的对象。我知道这是可能的,因为我已经测试了许多我没有编写的函数,并且创建的对象实际上是事实列表。不需要使用格式列表来扭曲或塑造已经存在的内容。我只是无法理解为什么有时候输出是列表或表格。我不知道魔法在哪里。但是我知道,在运行包含已创建对象的变量之前,当我运行$Host时,我会得
我需要的是创建一个内在输出列表(而不是表)的对象。我知道这是可能的,因为我已经测试了许多我没有编写的函数,并且创建的对象实际上是事实列表。不需要使用格式列表来扭曲或塑造已经存在的内容。我只是无法理解为什么有时候输出是列表或表格。我不知道魔法在哪里。但是我知道,在运行包含已创建对象的变量之前,当我运行
$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:\> $o1
c : 3
e : 5
d : 4
b : 2
a : 1
PS C:\> $o2
y x
- -
bar foo
PS C:\> $o1; $o2
c : 3
e : 5
d : 4
b : 2
a : 1
y : bar
x : foo
您还可以强制PowerShell通过管道将每个变量单独显示(例如)Out Default
:
PS C:\> $o2 | Out-Default; $o1 | Out-Default
y x
- -
bar foo
c : 3
e : 5
d : 4
b : 2
a : 1
但是,定义默认显示特性集不允许定义输出格式。要做到这一点,您可能需要编写一个自定义。为此,您可能还需要为对象定义一个
$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')
$formatFile=“$HOME\Documents\WindowsPowerShell\Your.Format.ps1xml”
$typeFile=“$HOME\Documents\WindowsPowerShell\Your.Type.ps1xml”
@'
违约
富吧
...
“@|设置内容$formatFile
更新FormatData-AppendPath$formatFile
@'
富吧
...
“@|设置内容$typeFile
更新TypeData-AppendPath$typeFile
$o2.PSTypeNames.Insert(0,'Foo.Bar')
杰弗里·希克斯写了一篇你可能想读的文章
尽管如此,我不建议你走这条路,除非你有非常令人信服的理由这样做。我之前试过解释,但说得比我简单得多,所以我要引用他的话: PowerShell不是bash,它将内容和表示分离,就像HTML和CSS一样
您通常希望在PowerShell中执行的操作是将数据保存在对象中,并使这些对象的属性包含“原始”(即未格式化)数据。这为您处理数据提供了最大的灵活性。格式化数据通常只会妨碍您,因为它会迫使您再次解析/转换数据。仅当需要将数据显示给用户时才格式化数据,并使用
Format-*
cmdlet来执行此操作。如果您的输出是为了进一步处理:首先不要麻烦格式化它。让用户自己决定如何显示数据。您真的希望快速/准确地回答这个冗长/嘈杂的问题吗?这个问题需要一个人同时阅读另一个问题?我做了,但我仍然不清楚你在追求什么。没有任何代码和/或输出,以及您所期望的,我将退出。谢谢您的评论。我只是在追求标题所暗示的东西。我只想创建一个输出列表的对象,而不是一个表。忘掉格式列表吧。假设您创建了一个对象,并且该对象输出了一个表或列表,那么首先是什么赋予了它这种格式呢?PowerShell(解释器)就是这样做的。默认情况下,最多具有4个特性的对象以表格形式显示,具有4个以上特性的对象以列表形式显示。用于定义自定义格式。您可能还需要定义一个。或者,您可以简单地不用麻烦而使用格式列表
。你选吧。@AnsgarWiechers你完全正确。这似乎是一种行为。我会看看你提供的材料。谢谢你也出现在这里。“我需要的是创建一个内在输出列表(而不是表)的对象。我知道这是可能的,因为我已经测试了许多我没有编写的函数,并且创建的对象实际上是列表。”-PowerShell不是bash,它有内容和表示的分离,就像HTML和CSS一样。函数输出对象。对象可以显示为列表或表格,也可以两者都不显示。函数本身不输出列表或表格。我不明白为什么这个答案只有+1。特别是关于保持数据“原始”的部分是Powershell中的一项重要实践。数据必须保持原始状态,直到您将其输出(到文件、控制台、gui表单或其他任何地方)。它能让你的代码清晰明了,还能防止初学者犯愚蠢的错误(比如在格式表之后导出csv)。@Ansgar:非常感谢你。我浏览了Jeffrey分享的每一行和所有文章。有太多的大事要抓。我认为这是迄今为止关于格式的最好解释。定制的ps1xml部分只是奶油上的一颗樱桃。表达敬意。
PS C:\> $o2 | Out-Default; $o1 | Out-Default
y x
- -
bar foo
c : 3
e : 5
d : 4
b : 2
a : 1
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 $members
PS C:\> $o1
c d
- -
3 4
PS C:\> $o1 | Format-List *
c : 3
e : 5
d : 4
b : 2
a : 1
$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')