6 votes

Comment écrire une liste triée lexicographiquement dans une grille classée par colonne ?

J'ai le résultat de Get-ChildItem et je veux itérer sur ceux-ci, et afficher leurs noms. Par défaut, si j'utilise simplement Write-Host puis je l'ai listé le long de la ligne comme ceci :

PerfLogs  Program Files  Program Files (x86)  Python31  Temp  Users  Windows

Cependant, si je sais que je veux qu'il soit divisé en x colonnes, je veux que le résultat soit comme ceci :

PerfLogs                  Python31     Windows
Program Files             Temp
Program Files (x86)       Users

Comme vous pouvez le voir, la liste est d'abord établie en bas des colonnes, puis en travers.

Vous savez comment obtenir un tel résultat ? Idéalement, il faudrait utiliser le plus grand nombre de colonnes possible sur l'écran, avec le nom aligné à gauche dans chaque colonne.

MISE À JOUR : grâce à Roman, je peux maintenant avoir ma sortie 'ls' de style linux avec des couleurs de répertoire. A partir de son script mis à jour, j'ai.. :

function color-ls
{
    dir $args | Format-High -Print {    
        $item = $args
        $fore = $host.UI.RawUI.ForegroundColor        
        $host.UI.RawUI.ForegroundColor = .{     
            if ($item[1].psIsContainer) {'Blue'}
            elseif ($item[1].Extension -match '\.(exe|bat|cmd|ps1|psm1|vbs|rb|reg|dll|o|lib)') {'Red'}
            elseif ($item[1].Extension -match '\.(zip|tar|gz|rar)') {'Yellow'}
            elseif ($item[1].Extension -match '\.(py|pl|cs|rb|h|cpp)') {'Cyan'}
            elseif ($item[1].Extension -match '\.(txt|cfg|conf|ini|csv|log|xml)') {'Green'}
            else {$fore}
        }
        write-host $args[0] -NoNewLine
        $host.UI.RawUI.ForegroundColor = $fore
    }
}

Sortie :

http://dl.dropbox.com/u/2809/lscolor.png

7voto

Roman Kuzmin Points 13913

C'est une idée et une tâche intéressantes.

MISE À JOUR : la mise à jour du script contient quelques corrections et améliorations. Il permet également de personnaliser la sortie de plusieurs façons. Voir les exemples dans les commentaires du script.

script Format-High.ps1 :

<#
.SYNOPSIS
    Formats input by columns using maximum suitable column number.

.DESCRIPTION
    Format-High prints the specified property, expression, or string
    representation of input objects filling the table by columns.

    It is named in contrast to Format-Wide which prints by rows.

.EXAMPLE
    # just items
    ls c:\windows | Format-High

    # ditto in colors based on PSIsContainer
    ls c:\windows | Format-High -Print {$c = if ($args[1].PSIsContainer) {'yellow'} else {'white'}; Write-Host $args[0] -ForegroundColor $c -NoNewline}

    # just processes, not good
    ps | Format-High

    # process names, much better
    ps | Format-High Name

    # custom expression and width
    ps | Format-High {$_.Name + ':' + $_.WS} 70

    # process names in colors based on working sets
    ps | Format-High Name 70 {$c = if ($args[1].WS -gt 10mb) {'red'} else {'green'}; Write-Host $args[0] -ForegroundColor $c -NoNewline}
#>

param
(
    [object]$Property,
    [int]$Width = $Host.UI.RawUI.WindowSize.Width - 1,
    [scriptblock]$Print = { Write-Host $args[0] -NoNewline },
    [object[]]$InputObject
)

# process the input, get strings to format
if ($InputObject -eq $null) { $InputObject = @($input) }
if ($Property -is [string]) { $strings = $InputObject | Select-Object -ExpandProperty $Property }
elseif ($Property -is [scriptblock]) { $strings = $InputObject | ForEach-Object $Property }
else { $strings = $InputObject }
$strings = @(foreach($_ in $strings) { "$_" })

# pass 1: find the maximum column number
$nbest = 1
$bestwidths = @($Width)
for($ncolumn = 2; ; ++$ncolumn) {
    $nrow = [Math]::Ceiling($strings.Count / $ncolumn)
    $widths = @(
        for($s = 0; $s -lt $strings.Count; $s += $nrow) {
            $e = [Math]::Min($strings.Count, $s + $nrow)
            ($strings[$s .. ($e - 1)] | Measure-Object -Maximum Length).Maximum + 1
        }
    )
    if (($widths | Measure-Object -Sum).Sum -gt $Width) {
        break
    }
    $bestwidths = $widths
    $nbest = $ncolumn
    if ($nrow -le 1) {
        break
    }
}

# pass 2: print strings
$nrow = [Math]::Ceiling($strings.Count / $nbest)
for($r = 0; $r -lt $nrow; ++$r) {
    for($c = 0; $c -lt $nbest; ++$c) {
        $i = $c * $nrow + $r
        if ($i -lt $strings.Count) {
            & $Print ($strings[$i].PadRight($bestwidths[$c])) $InputObject[$i]
        }
    }
    & $Print "`r`n"
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X