Wie eine Liste schreiben lexikografisch in einem Raster von Spalte aufgeführt sortierten?
-
29-09-2019 - |
Frage
Ich habe das Ergebnis Get-ChildItem
, und ich möchte diese iterieren, und ihre Namen anzuzeigen. Standardmäßig, wenn ich einfach Write-Host
verwenden dann bekomme ich es entlang der Zeile wie folgt aufgelistet aus:
PerfLogs Program Files Program Files (x86) Python31 Temp Users Windows
Allerdings sagen, dass ich weiß, ich will es in x Spalten aufgeteilt, möchte ich die Ausgabe wie folgt statt:
PerfLogs Python31 Windows
Program Files Temp
Program Files (x86) Users
Wie Sie sehen können, es listet es auf die Spalten zuerst, und dann über.
Jede Idee, wie eine Ausgabe wie das zu bekommen? Im Idealfall wäre es die Beste Anzahl der Spalten verwenden, wie auf dem Bildschirm mit dem Namen ausgerichtet nach links in jeder Spalte passen.
UPDATE: Dank Roman, ich kann jetzt meinen Linux-Stil ‚ls‘ Ausgabe mit Verzeichnis Farben hat. Aufbauend auf seiner aktualisierten Skript habe ich:
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
}
}
Ausgabe:
Lösung
Es ist eine interessante Idee und Aufgabe.
UPDATE: das aktualisierte Skript enthält einige Korrekturen und Verbesserungen. Es ermöglicht auch die Ausgabe auf verschiedene Weise anpassen. Siehe Beispiele in dem Skriptkommentar.
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"
}