有没有办法对Powershell cmdlet的结果进行自动换行?

时间:2009-06-29 18:10:20

标签: powershell

简单(可能是愚蠢的)问题。我是一个Powershell新手,我主要使用它来实例化托管库,所以当我需要使用它们的成员时,我不必编写小应用程序。其中一些库是旧的,并且具有长而痛苦的签名方法。在使用new-object实例化后使用get-member,我经常遇到令人沮丧的结果:

PS> $object | get-member MethodWithLongSignature

TypeName: SomeLib.SomeObject

Name                      MemberType Definition
----                      ---------- ----------
MethodWithLongSignature   Method     System.Void MethodWithLongSignature(string param1, int param2, string param3, string param4, stri....

有没有办法包装get-member的结果?或者,是否有一个get-member开关,它将以不会换行的方式产生结果?

7 个答案:

答案 0 :(得分:18)

表结构中的输出是自动格式化的,以适应屏幕的宽度,必要时在过程中截断长值。

将结果传递到format-list命令,以获得结果的详细,垂直格式。

PS> $object | get-member MethodWithLongSignature | format-list

答案 1 :(得分:4)

Format-Table有一个-Wrap开关来包装最后一列。由于Get-Member输出的最后一列已经非常大,这将产生可读的结果。

另一个选项是Format-Wide(但它没有换行,所以你只限于控制台宽度):

Get-Process | Get-Member | Format-Wide Definition -Column 1

答案 2 :(得分:4)

我无法找到内置的内容,允许自动换行到任意宽度,所以我写了一个 - 有点冗长,但这里是:

function wrapText( $text, $width=80 )
{
    $words = $text -split "\s+"
    $col = 0
    foreach ( $word in $words )
    {
        $col += $word.Length + 1
        if ( $col -gt $width )
        {
            Write-Host ""
            $col = $word.Length + 1
        }
        Write-Host -NoNewline "$word "
    }
}

答案 3 :(得分:3)

根据Leo的回答,我决定制作一个word-wrap cmdlet。

<#
.SYNOPSIS
wraps a string or an array of strings at the console width without breaking within a word
.PARAMETER chunk
a string or an array of strings
.EXAMPLE
word-wrap -chunk $string
.EXAMPLE
$string | word-wrap
#>
function word-wrap {
    [CmdletBinding()]
    Param(
        [parameter(Mandatory=1,ValueFromPipeline=1,ValueFromPipelineByPropertyName=1)]
        [Object[]]$chunk
    )
    PROCESS {
        $Lines = @()
        foreach ($line in $chunk) {
            $str = ''
            $counter = 0
            $line -split '\s+' | %{
                $counter += $_.Length + 1
                if ($counter -gt $Host.UI.RawUI.BufferSize.Width) {
                    $Lines += ,$str.trim()
                    $str = ''
                    $counter = $_.Length + 1
                }
                $str = "$str$_ "
            }
            $Lines += ,$str.trim()
        }
        $Lines
    }
}

它既可以通过传递字符串或字符串数​​组作为函数参数,也可以在管道上传递。例子:

$str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. " * 5

word-wrap $str
$str | word-wrap
get-content txtfile.txt | ?{ $_ } | sort | word-wrap

函数顶部的元数据注释块允许get-help word-wrap显示一些有用的信息。 See this page了解有关定义管道cmdlet的更多信息。

答案 4 :(得分:1)

您也可以尝试使用format-table -wrap,例如:

(get-process -id 3104).startinfo.EnvironmentVariables | format-table -wrap

答案 5 :(得分:0)

作为替代方案,您可以使用&#34; PowerShell Tools for Visual Studio 2015&#34;在VS 2015中运行PowerShell脚本的扩展。

https://marketplace.visualstudio.com/items?itemName=AdamRDriscoll.PowerShellToolsforVisualStudio2015&showReviewDialog=true

这为您提供了所有VS编辑器功能,自动换行,调试,智能感知等。

答案 6 :(得分:0)

我喜欢@Leo和@rojo答案背后的意图,但是对于大量文本而言,分隔行是不合适的,而且状态机(或者更好的是,一个易于编程的状态机,如regex)将更加高效。 / p>

在编写自己的复杂解决方案之上,我保证了它的复杂性,因为它在原始字符串中保持换行符,甚至允许您对某些字符强制换行 >

Wrap -Length 30 -Force '.' "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."

在这里,我尝试折断30个字符,找到最接近的空格,但也要在句号处强制中断,忽略单词中的句点,并确保不要折断由于句点而已经折断的行。

Lorem Ipsum is simply dummy
text of the printing and
typesetting industry.
Lorem Ipsum has been the
industry's standard dummy text
ever since the 1500s, when an
unknown printer took a galley
of type and scrambled it to
make a type specimen book.
It has survived not only five
centuries, but also the leap
into electronic typesetting,
remaining essentially
unchanged.
It was popularised in the
1960s with the release of
Letraset sheets containing
Lorem Ipsum passages, and more
recently with desktop
publishing software like Aldus
PageMaker including versions
of Lorem Ipsum.

这是函数本身,但请注意,您需要在该答案的底部填写正则表达式(我将其放在较高位置以便可以读取参数)

Function Wrap {
    Param (
        [int]$Length=80,
        [int]$Step=5,
        [char[]]$Force,
        [parameter(Position=0)][string]$Text
    )
    $key="$Length $Step $Force"
    $wrap=$_WRAP[$key]
    if (!$wrap) {
        $wrap=$_WRAP[$key]=_Wrap `
            -Length $Length `
            -Step $Step `
            -Force ($Force -join '') `
        | Concat -Join '|' -Wrap '(',')(?:[^\n\r\S])+'
    }
    return $Text -replace $wrap,$_WRAP['']
}

在这里可以显示其多功能性。
不用担心脚本的其余部分,它们是colours/backgroundsemailingGridView
基本上,它会执行大量ping,tcp检查和http请求,并将错误消息放入info属性中:

        $_.info=(
            $style.bf.yellow, `
            (Wrap -Length 55 -Force ':.' $_.info), `
            $colour `
        | Concat)

enter image description here

您将需要以下Wrap

定义的以下实用程序功能
Function Concat {
    Param ([switch]$Newlines, $Wrap, $Begin='', $End='', $Join='')
    Begin {
        if ($Newlines) {
            $Join=[System.Environment]::NewLine
        }
        $output=[System.Text.StringBuilder]::new()
        $deliniate=$False

        if (!$Wrap) {
            $output.Append($Begin) | Out-Null
        }
        elseif ($Wrap -is [string]) {
            $output.Append(($End=$Wrap)) | Out-Null
        }
        else {
            $output.Append($Wrap[0]) | Out-Null
            $End=$Wrap[1]
        }
    }
    Process {
        if (!($_=[string]$_).length) {
        }
        elseif ($deliniate) {
            $output.Append($deliniate) | Out-Null
            $output.Append($_) | Out-Null
        }
        else {
            $deliniate=$Join
            $output.Append($_) | Out-Null
        }
    }
    End {
        $output.Append($End).ToString()
    }
}

$_WRAP=@{''="`$1$([System.Environment]::NewLine)"}
Function _Wrap {
    Param ($Length, $Step, $Force)

    $wrap=$Force -join '' -replace '\\|]|-','\$0'
    $chars="^\n\r$wrap"
    $preExtra="[$chars\S]*"
    $postExtra="[^\s$wrap]"

    $chars="[$chars]"
    $postChars="$preExtra$postExtra"
    if ($wrap) {
        $wrap="[$wrap]"
        $wrap
        $wrap="$wrap(?=\S)"
        $chars="$chars|$wrap"
        $postChars="$postChars|$preExtra$wrap"
    }

    for (
        ($extra=0),($next=$NULL),($prev=$NULL);
        ($next=$Length - $Step) -gt 0 -and ($prev=$extra + $Step);
        ($Length=$next),($extra=$prev)
    ) {
        "(?:$chars){$next,$Length}(?=(?:$postChars){$extra,$prev})"
    }
}
相关问题