我正在尝试在PowerShell中获得类似UNIX ls
输出的内容。到了那里:
Get-ChildItem | Format-Wide -AutoSize -Property Name
但它仍然以行主要而不是列主要顺序输出项目:
PS C:\Users\Mark Reed> Get-ChildItem | Format-Wide -AutoSize -Property Name
Contacts Desktop Documents Downloads Favorites
Links Music Pictures Saved Games
Searches Videos
期望的输出:
PS C:\Users\Mark Reed> My-List-Files
Contacts Downloads Music Searches
Desktop Favorites Pictures Videos
Documents Links Saved Games
不同之处在于排序:1 2 3 4 5/6 7 8 9阅读各行,与1/2/3 4/5/6 7/8/9读取列。
我已经有了一个脚本,它将采用数组并使用Write-Host
按列主要顺序打印出来,但我通过阅读Keith和Roman的内容,发现了很多PowerShellish惯用的改进。但是我从阅读中得到的印象是,这是错误的做法。脚本应该输出对象,而不是调用Write-Host
,而是让格式化器和输出器负责将正确的东西写入用户的控制台。
当脚本使用Write-Host
时,其输出不可捕获;如果我将结果赋给变量,我得到一个空变量,无论如何输出都被写入屏幕。它就像一个UNIX管道中间的命令直接写入/dev/tty
而不是标准输出甚至是标准错误。
不可否认,我可能无法对Microsoft.PowerShell.Commands.Internal.Format
。*对象的数组做多少工作。 Format-Wide
,但至少它包含输出,它不会以流氓方式显示在我的屏幕上,并且我可以随时通过将数组传递给另一个格式化程序或输出器来重新创建。
答案 0 :(得分:3)
这是一个简单的函数,用于格式化列主要。您可以在PowerShell脚本中完成所有操作:
function Format-WideColMajor {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
[AllowNull()]
[AllowEmptyString()]
[PSObject]
$InputObject,
[Parameter()]
$Property
)
begin {
$list = new-object System.Collections.Generic.List[PSObject]
}
process {
$list.Add($InputObject)
}
end {
if ($Property) {
$output = $list | Foreach {"$($_.$Property)"}
}
else {
$output = $list | Foreach {"$_"}
}
$conWidth = $Host.UI.RawUI.BufferSize.Width - 1
$maxLen = ($output | Measure-Object -Property Length -Maximum).Maximum
$colWidth = $maxLen + 1
$numCols = [Math]::Floor($conWidth / $colWidth)
$numRows = [Math]::Ceiling($output.Count / $numCols)
for ($i=0; $i -lt $numRows; $i++) {
$line = ""
for ($j = 0; $j -lt $numCols; $j++) {
$item = $output[$i + ($j * $numRows)]
$line += "$item$(' ' * ($colWidth - $item.Length))"
}
$line
}
}
}