比 Write-Host 更好的打印对象的方法

发布于 2024-07-18 03:31:44 字数 292 浏览 3 评论 0原文

我使用 Write-Host 分析对象,但有时很难理解对象实际上是什么。

考虑:

Write-Host $null
Write-Host @()
Write-Host @($null, $null)

打印:

# Actually it prints nothing

我想要这样的东西:

Null
@()
@(Null, Null)

有什么建议吗?

I use Write-Host analyze objects, but some times it is hard to understand what the object actually is.

Consider:

Write-Host $null
Write-Host @()
Write-Host @($null, $null)

Prints:

# Actually it prints nothing

I would like some thing like this:

Null
@()
@(Null, Null)

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

泪痕残 2024-07-25 03:31:44

对于这个特定的示例,您可以通过将它们粘贴到对象的属性中轻松获得您想要的东西。 作为示例,让我们创建一个包含三个测试的数组:

$tests = @($null,@(), @($null,$null))

function Write-Visible {
   param($InputObject) 

   New-Object PSObject -Property @{ Object=$InputObject } | 
       Out-String | Out-Host 
}

当然,Out-String | Out-Host 的东西只是为了确保我们实际上不会将对象输出到管道,而是像 Write-Host 那样表现。

现在我们可以运行我们的测试了:

PS> Write-Visible $tests[0]

Object
------


PS> Write-Visible $tests[1]

Object
------
{}


PS> Write-Visible $tests[2]

Object
------
{$null, $null}

当然,问题是它对于真实对象来说效果不太好,因为它将它们变成了对象的属性,它们被渲染为“ToString()”……但是,在我的脑海中,我无法想象如何在没有新对象的情况下调用在那里发生的渲染魔法。

For this specific example, you can easily get what you want by sticking them in the property of an object. For the sake of an example, lets create an array with your three tests in it:

$tests = @($null,@(), @($null,$null))

function Write-Visible {
   param($InputObject) 

   New-Object PSObject -Property @{ Object=$InputObject } | 
       Out-String | Out-Host 
}

Of course, the Out-String | Out-Host stuff is just to make sure we don't actually output the objects to the pipeline, but behave like Write-Host does.

So now we can run our tests:

PS> Write-Visible $tests[0]

Object
------


PS> Write-Visible $tests[1]

Object
------
{}


PS> Write-Visible $tests[2]

Object
------
{$null, $null}

Of course, the problem with that is that it tends not to work so great for real objects because it's turning them into properties of an object, where they get rendered "ToString()" ... however, off the top of my head, I can't think how to invoke the rendering magic that happens there without the new object.

江湖正好 2024-07-25 03:31:44

您可以编写一个函数来为您进行漂亮的打印。 类似下面的内容可能会满足您的需求:

function pp($a) {
    if ($a -eq $null) {
        return "Null"
    } elseif ($a -is [object[]]) {
        $b = @()
        foreach ($x in $a) {
            $b += (pp $x)
        }
        $s = "@(" + [string]::Join(",", $b) + ")"
        return $s
    } else {
        return $a
    }
}

但是,这对于 shell 上的空数组仍然存在问题(不过,在 .ps1 文件中工作正常)。 另外,不支持哈希表,但支持嵌套数组。 可能仍然需要一些管道,但可能会给出一个总体方向。

@($null, $null) 数组似乎是一个丑陋的野兽,甚至拒绝将其与 $null 进行比较。 诡异的。

You can write a function that does the pretty-printing for you. Something like the following might work for your needs:

function pp($a) {
    if ($a -eq $null) {
        return "Null"
    } elseif ($a -is [object[]]) {
        $b = @()
        foreach ($x in $a) {
            $b += (pp $x)
        }
        $s = "@(" + [string]::Join(",", $b) + ")"
        return $s
    } else {
        return $a
    }
}

This has, however still problems with an empty array on the shell (works fine from a .ps1 file, though). Also Hashtables aren't supported, but nested arrays are. Probably still needs some plumbing but might give a general direction.

The @($null, $null) array seems to be an ugly beast, resisting even comparing it to $null. Weird.

半暖夏伤 2024-07-25 03:31:44

尝试做这样的事情将会遇到多个问题。

  1. 更改 write-host 工作方式的“正确”或“powershell”方法是使用格式化文件来定义您希望使用的主机如何显示相关对象。 您可以从 get-help about_format.ps1xmlMSDN PowerShell 格式化文件 页面。
  2. 您需要特定于您正在使用的“主机”。 有关详细信息,请参阅 get-help get-hostTechNet 页面。 您需要了解至少三种常见主机:
    • 基本命令行,ConsoleHost
    • 基本 PowerShell ISE、Windows PowerShell ISE 主机
    • Quest PowerGUI 主机,PowerGUIScriptEditorHost
  3. PowerShell 处理@() 语法以一种特殊的方式,有时会使处理空数组变得困难。 根据 此 MSDN PowerShell 博客文章
    <块引用>

    ...

    @( … )

    操作是

    [array] 的语法糖$( … )

    所以 – 如果 @() 中的语句返回一个标量,它将被包装在一个数组中,但如果结果已经是一个数组,那么它就不会嵌套...

我很乐意能够为此提供一些代码,但它有点超出了此时的我...

There are going to be multiple issues trying to do something like this.

  1. The "correct" or "powershell" way to change how write-host works is to use formatting files to define how you want the host you're using to display the objects in question. You can get more info from get-help about_format.ps1xml, or from the MSDN PowerShell Formatting File pages.
  2. You need to be specific to the "host" you are using. See get-help get-host for more info, or the TechNet page. There are AT LEAST three common hosts you want to be aware of:
    • the basic command-line, ConsoleHost
    • the basic PowerShell ISE, Windows PowerShell ISE Host
    • the Quest PowerGUI host, PowerGUIScriptEditorHost
  3. PowerShell handles the @() syntax in a special way, which can make dealing with empty arrays a difficult sometimes. According to this MSDN PowerShell Blog post:

    ... the

    @( … )

    operation is syntactic sugar for

    [array] $( … )

    So – if the statements in @() return a scalar, it will be wrapped in an array but if the result is already an array, then it won't be nested...

I'd love to be able to provide some code for this, but it's a bit beyond me at this point...

凝望流年 2024-07-25 03:31:44

对于空数组效果不佳,但您可以使用 format-xxx 命令之一。
这有助于格式化没有有用的 ToString 覆盖的对象。
例如

> $cmd = Get-Command -Name get-command
> $cmd

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command...

> write-host $cmd
Get-Command
> format-table -InputObject $cmd | out-string | out-host

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command... 

Doesn't work well for the empty arrays, but you could use one of the format-xxx commands.
This helps for formatting objects that don't have a helpful ToString override.
E.g.

> $cmd = Get-Command -Name get-command
> $cmd

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command...

> write-host $cmd
Get-Command
> format-table -InputObject $cmd | out-string | out-host

CommandType     Name                                                Definition
-----------     ----                                                ----------
Cmdlet          Get-Command                                         Get-Command... 
不如归去 2024-07-25 03:31:44

你可以试试这个:

Write-Host '$null'
Write-Host '@()'
Write-Host '@($null, $null)'

You could try this:

Write-Host '$null'
Write-Host '@()'
Write-Host '@($null, $null)'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文