【问题标题】:Is there an easy way to have Powershell always show the actual value?有没有一种简单的方法可以让 Powershell 始终显示实际值?
【发布时间】:2020-10-17 12:45:37
【问题描述】:

这些事情让我抓狂:

有没有一种简单的方法让 Powershell 只显示空字符串和包含空字符串的列表?

【问题讨论】:

  • 它就是这样做的。您期望或希望得到什么确切的输出?
  • 像 node.js 那样,或者 lisp: '', ('')
  • ConvertTo-Json $(expression)?
  • 我喜欢这个想法(这对我来说很简单),但它并不完全做到:无论是否在列表中,$false 或 '' 的结果都是一样的。啊,也许不是!我将它通过管道传输到 convertto-json,但是当我将它作为参数提供时,我得到了不同的结果.. Tnx!
  • 那是因为“一个字符串”和“一个字符串的数组”之间没有功能上的区别,管道消耗1个字符串。 PowerShell 不是节点 :)

标签: powershell


【解决方案1】:

有一段时间我正在维护一个ConvertTo-Expression,它将一个(复杂的)对象转换为最终可用于重建大多数对象的 PowerShell 表达式。它在比较测试结果的情况下可能很有用,但也可以显示对象。详情见:readme

源码和安装

ConvertTo-Expression 脚​​本可以从 PowerShell 库安装:

Install-Script -Name ConvertTo-Expression

由于它涉及独立脚本,因此实际上并不需要安装。如果您没有管理员权限,您可能只需将脚本下载(或复制)到所需位置。您可能不仅仅使用 PowerShell 点源调用脚本:

. .\ConvertTo-Expression.ps1

示例

以下命令输出与构建对象相同的表达式:

$Object = [Ordered]@{
    'Null' = $Null
    'EmptyString' = ''
    'EmptyArray' = @()
    'SingleItem' = ,''
    'EmptyHashtable' = @{}
}
ConvertTo-Expression $Object

注意@Mathias的评论“一个字符串”和“一个字符串的数组”之间没有功能区别,管道消耗1个字符串。 PowerShell 不是此处描述的节点PowerShell enumerate an array that contains only one inner array有些对象可能与您的预期完全不同

另见:Save hash table in PowerShell object notation (PSON)

【讨论】:

    【解决方案2】:

    这是 PowerShell,而不是 Node。所以它不是 JavaScript 或 JSON。此外,PowerShell 不是 Bash 或 CMD 任何其他常规的基于文本的 shell。 PowerShell 适用于对象。 .NET 对象,尤其是。以及如何将对象表示为文本……这完全是一个品味问题。如何表示空?当然:什么都没有。如何表示一个空字符串?也没什么。一个空数组......你明白我的意思。

    所有管道输出默认发送到Out-Default。一般来说,对象的表示方式可以通过格式文件来控制:about_Format.ps1xmlabout_Types.ps1xml。从 PowerShell 6 开始,默认格式被编译到源代码中,但您可以扩展它们。你如何做到这一点,取决于你的个人品味。已经提到了一些选项ConvertTo-Json ""ConvertTo-Json @("")),但这将是 veryyy JSON 特定的。

    tl;dr 不要太在意对象在文本中的表示方式。如您所见,有很多可能的方法可以做到这一点,还有一些others。只要确保您的脚本始终是面向对象的即可。

    【讨论】:

      【解决方案3】:

      你的意思是像 Python 的 repr() 函数?连载? “给我一个对象的规范表示,当属性评估时,它将返回一个最初传递的类型的对象?”不,除非您自己编写或将其序列化为 XML、JSON 或类似文件,否则这是不可能的。这就是 *-CliXmlConvertTo-*/ConvertFrom-* 命令的用途。

      在 Powershell 7 上:

      PS C:\> ''.Split(',') | ConvertTo-Json -Compress -AsArray
      [""]
      PS C:\> '1,2,3,,5'.Split(',') | ConvertTo-Json -Compress -AsArray
      ["1","2","3","","5"]
      

      最接近的是ToString() 常用方法。但是,这是用于格式化输出和类型转换,而不是规范表示或序列化。并非每个对象都具有可以转换回该对象的字符串表示形式。该语言的设计并未考虑到这一点。它基于 C#,一种支持二进制序列化的编译语言。 Javascript 基本上要求所有内容都具有字符串序列化,以实现其原始设计。 Python 也将字符串表示作为其设计的基础,这就是为什么 repr() 函数是序列化和内省等的基础。

      C# 和 .Net 则相反。在 .Net 应用程序中,如果要指定文字空字符串,建议您使用 String.Empty(Powershell 中为 [String]::Empty),因为它更容易看出它是显式的。为什么你会希望一个编译的应用程序告诉用户一个对象在内存中的规范表示?你明白为什么这对 C# 没有用,即使它可能对 Powershell 有用?

      【讨论】:

      • 很好的指针,但是通过使用-AsArray,您人为地将任何输入转换为数组,即使不是。如 cmets 中的 Mathias 所示,将表达式作为 参数 传递:ConvertTo-Json -Compress (''.Split(',')) - 这也使其在早期版本中工作。
      • @mklement0 这是故意的。他的代码示例代码试图把它变成一个数组。我不清楚他打算 @() 做什么,所以我假设他想要它作为一个数组。
      • 我认为 OP 有一种误解,即 ''.split(',') 将空字符串作为 单个字符串 返回,而实际上它与 '@('.split(',')) 相同(几乎,给定前者返回[string[]],后者返回[object[]])。以诊断方式打印这些表达式的值 as-is 可以消除这种特殊的误解,并且通常也有助于区分标量和数组。
      • @mklement0 这是可能的,但我认为这不是一个真正有用的区别。我认为OP必须理解我的答案并不明确。首先,我认为如果您要使用String.Split(),您将编写处理数组的代码,其次,Powershell 在很大程度上以相同的方式处理标量和数组。我认为一致性更重要。如果您仍然不同意并想争论单元素数组与标量的细节,欢迎您添加自己的答案。我认为这无关紧要。
      • 我的意思是您的答案不符合问题标题中要求的“显示实际值”的要求,并且已被接受的答案所满足:精确表示实际值的能力以一种诊断形式,您可以判断它是标量,数组还是嵌套数组,......是这个问题的内容(正如您的答案开头所暗示的那样)以及让未来变得有趣的原因读者。很高兴把它留在那里(不需要另一个答案 - 接受的答案已经涵盖了)。
      猜你喜欢
      • 1970-01-01
      • 2011-08-23
      • 2011-08-31
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多