Powershell:自动调整大小和特定列宽

时间:2014-03-28 22:02:20

标签: powershell powershell-v2.0

基于这个SO问题Powershell: Output collection of objects,我能够在一列中包含多行的字符串集合。但是,当我尝试将集合输出到表视图时,自动调整大小将不允许我指定特定的列宽。

例如:

id     name     items                                                          others
---    ----     -----                                                          -----
01     a        ("The first item", "The second item", "The third item", "...")  ...
02     ....

这是我的输出:

$colObjs | Select-object id, name, items, others`
   @{Expression={($_.items -join "`n")};Label="Items"} | `
   Format-table -autosize -wrap

然后items列将是其数组中字符串的整个长度:

id     name     items                                                          others
---    ----     -----                                                          -----
01     a        "The first item"                                               ...
                "The second item"                                              ....
                "The third item"
                ...
02     ....

我尝试使用以下代码,items列的宽度仍然不符合预期:

$colObjs | Select-object id, name, items, others `
   @{Expression={($_.items -join "`n")};Label="Items"} | `
   Format-table id, name, `
     @{expression={$_.items}; label="items"; width=18}, others `
   -autosize -wrap

特别是,如果items有很长的字符串列表,那么表格视图看起来非常难看,items列中的空格太多。

这是我想要的格式:

id     name     items              others
---    ----     -----              -----
01     a        "The first item"   ...
                "The second item"  ....
                "The third item"
                ...
02     ....

这是真的--autosize会使宽度无效吗?如何指定items的宽度并将其他列保留为自动调整大小?

3 个答案:

答案 0 :(得分:4)

这里的方法略有不同。循环浏览您的集合,为每个集合查找每个属性的计数并选择最高计数。通过那么多循环运行该集合,并在每个循环上创建一个自定义对象,其中每个属性检查它是否是一个数组。如果它是迭代到该数组,如果它不是它检查这是否是第一轮自定义对象并返回值,否则它返回一个空白。输出正是您正在寻找的,而且-AutoSize for FT可以很好地工作。

首先,我制作了一个类似于你的集合:

$col = @(

    (New-Object –TypeName PSObject –Prop @{'id'='01';'name'='a';'items'=@(1,2,3);'others'=@('SampleA1','SampleA2')}),
    (New-Object –TypeName PSObject –Prop @{'id'=@('02a','02b');'name'='b';'items'=@(1,2,3);'others'=@('SampleB1','SampleB2','SampleB3','SampleB4','SampleB5')}),
    (New-Object –TypeName PSObject –Prop @{'id'='03';'name'=@('c1','c2');'items'=@(1,2,3);'others'='SampleC'})
    )

然后我通过我建议的代码运行它:

$Col|%{
    $Current = $_
    $Members = $_|GM|?{$_.MemberType -match "Property"}|Select -ExpandProperty Name
    $Rows = ($Members|%{$current.$_.count}|sort -Descending|Select -First 1)-1
    For($i=0; $i -le $Rows;$i++){
        $LoopObject = New-Object PSObject -Property @{$($Members[0]) = if($Current.$($Members[0]).count -gt 1){$Current.$($Members[0])[$i]}else{if(!($i -gt 0)){$Current.$($Members[0])}else{$Null}}}
        If($Members.Count -gt 1){
            $Members[1..$Members.count]|%{
                Add-Member -InputObject $LoopObject -MemberType NoteProperty -Name $_ -Value $(if($Current.$_.count -gt 1){$Current.$_[$i]}else{if(!($i -gt 0)){$Current.$_}else{$Null}})
            }
        }
    $LoopObject
    }
}|FT ID,Name,Items,Others -AutoSize

它给了我这个输出:

id  name items others  
--  ---- ----- ------  
01  a        1 SampleA1
             2 SampleA2
             3         
02a b        1 SampleB1
02b          2 SampleB2
             3 SampleB3
               SampleB4
               SampleB5
03  c1       1 SampleC 
    c2       2         
             3 

编辑:好的,更新了我的代码。它不再关心你抛出的数组,它有多少属性,或者这些属性有多少属性。只要给定的集合只包含字符串和/或数组,它就会输出所需的对象集合,就像上面提到的输出一样。

答案 1 :(得分:2)

我明白你的意思了,我没有答案留在控制台内,但如果你这样做就把它发送到Out-GridView:

$col = @(

    (New-Object –TypeName PSObject –Prop @{'id'='01';'name'='a';'items'=@('the first item','the second item', 'the third item')}),
    (New-Object –TypeName PSObject –Prop @{'id'='02';'name'='b';'items'=@('the first item','the second item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item', 'the third item')}),
    (New-Object –TypeName PSObject –Prop @{'id'='03';'name'='c';'items'=@('the first item','the second item', 'the third item')})
    )

$col|Select -p id,@{E={$_.items -join "`n"};L="Items"},name | Out-GridView

(我修剪了'Expression'和'Label =',因此它们适合屏幕)。

然后GridView显示宽度正确的列。

所以如果GridView可以,为什么不能格式化表?也许你可以使用自定义视图绕过它 - http://www.adminarsenal.com/admin-arsenal-blog/bid/43912/PowerShell-Tips-for-System-Administrators-Format-Views,我没有尝试过这种方法。

答案 2 :(得分:0)

这是一个例子

F:\> $array|format-table RecordType,
$array|Format-Table @{Label= "RecordType";Expression={ $_.RecordType};             Width = 10 }, `
                @{Label= "Date"      ;Expression={ $_.date};                   Width = 8 },`
                @{Label= "Time"      ;Expression={ $_.Time};                   Width = 8 },`
                @{Label= "code"      ;Expression={ $_.code}},`
                @{Label = "sales"    ;Expression={ [math]::Round($_.sales,2)} }