PowerShell对象表示

kcrjzv8t  于 2023-03-23  发布在  Shell
关注(0)|答案(2)|浏览(149)

在PowerShell中有不同的方法来表示(显示)对象,但当涉及到复杂对象时,它要么非常冗长,要么毫无用处:

$Object = @{ 'a' = 1; 'b' = 2 }

只输出(Format-HostFormat-List)就返回多行输出,如下所示:

$Object

Name                           Value
----                           -----
a                              1
b                              2

将其转换为字符串"$Object"$Object.ToString()不会显示其内容的任何信息:

System.Collections.Hashtable

将其转换为Json $Object |ConvertTo-Json -Compress,接近我希望看到的内容(但对于我所需要的内容来说,有点太具表现力的cmdlet):

{"a":1,"b":2}

我想知道是否有一种方法可以访问PowerShell显示cmdlet使用的表示格式,例如ImmediateBaseObjectBaseObject背后的值:

$Object.PSObject

Members             : {System.Object Item(System.Object key) {get;set;}, bool IsReadOnly {get;}, bool IsFixedSize {get;}, bool IsSynchronized {get;}…}
Properties          : {bool IsReadOnly {get;}, bool IsFixedSize {get;}, bool IsSynchronized {get;}, System.Collections.ICollection Keys {get;}…}
Methods             : {Add, Clear, Clone, Contains…}
ImmediateBaseObject : {[a, 1], [b, 2]}                     # <-- This representation
BaseObject          : {[a, 1], [b, 2]}                     #
TypeNames           : {System.Collections.Hashtable, System.Object}

一厢情愿地想,我希望能够做这样的事情:

[PowerShellFormat]$Object

并为任何(复杂)对象返回相同的格式,如BaseObject后面的$Object.PSObject所示。
至于这个案子:

{[a, 1], [b, 2]}
x4shl7ld

x4shl7ld1#

JosefZ提供了关键指针:

  • 在您的dictionary上调用.GetEnumerator(),以便枚举其 entries,这些条目是键值对,例如hashtable示例中的[System.Collections.DictionaryEntry]类型。
  • 与字典 * 作为一个整体 * 不同,它们的 * 条目 * 以[<key>, <value>]的形式进行有意义的字符串化-尽管重要的是要注意这只是一个 * 用于显示 * 的表示,不适合 * 编程 * 处理。
  • 当PowerShell的格式化系统将存储在输入对象的 * 属性 * 中的字典字符串化时,它将其视为 * 条目数组 *,并将该数组字符串化 * 类似于 * 可扩展 * 字符串中的数组字符串化:
  • 不同之处在于整个表示被包含在{...}中,并且(字符串化的)元素用,分隔。您可以在@{ 'a' = 1; 'b' = 2 }.psobject的显示格式(.ImmediateBaseObject.BaseObject属性)中看到这一点。
  • 我不知道有什么公共方法可以生成这种格式,但自己生成并不难:
# -> '{[a, 1], [b, 2]}'
'{' + (@( @{ 'a' = 1; 'b' = 2 }.GetEnumerator() ) -join ', ') + '}'

注:

  • .GetEnumerator()调用必须 Package 在@(...)中以强制实际枚举,从而导致 array
  • 因此,你也可以使用上面的for arrays 作为输入。

获取类似的字符串表示或**[pscustomobject]**示例要简单得多:使用 string interpolation,即将对象嵌入到可扩展(双引号)字符串("...")中:

$obj = [pscustomobject] @{ 'a' = 1; 'b' = 2 }
"$obj" # -> '@{a=1; b=2}'

注:

  • 与哈希表/字典不同,[pscsutomobject]示例在可扩展字符串中以 * 相同的方式 * 进行字符串化,并作为格式化对象表示的属性。
  • 请注意与哈希表可视化相比的格式差异,属性名称-值对用=分隔(并且没有空格),多个属性用;分隔,@{作为开始分隔符。

奇怪的是,这种格式与 hashtable 文字的语法非常相似。
最后,为了证明PowerShell的格式化系统确实为哈希表和[pscustomobject]示例生成了上面的表示,并使用 * 作为属性 *:

@{ 
  hashtable = @{ 'a' = 1; 'b' = 2 }
  pscustomobject = [pscustomobject] @{ 'a' = 1; 'b' = 2 }
}

输出:

Name                           Value
----                           -----
pscustomobject                 @{a=1; b=2}
hashtable                      {[a, 1], [b, 2]}
5hcedyr0

5hcedyr02#

试试这个:

$object = @{'a'=1; 'b'=2}
$x = [pscustomobject]$object

'Members'
$x | gm
'  '
'Content'
$x
'  '
'Properties'
$x.a
$x.b
'   '
'CSV format'
$x | ConvertTo-csv
'   '
'Json format'
$x | ConvertTo-Json

这将把a和B转换为Noteproperty名称,并带有相应的值。

相关问题