在Powershell中模拟`ls`

时间:2015-06-27 00:13:32

标签: powershell

我正在尝试在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,但至少它包含输出,它不会以流氓方式显示在我的屏幕上,并且我可以随时通过将数组传递给另一个格式化程序或输出器来重新创建。

1 个答案:

答案 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
        }
    }
}