2015-06-27 82 views
3

我试图在PowerShell中获得类似UNIX ls输出的内容。这是越来越有:在Powershell中模拟`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读取整个行,vs 1/2/3 4/5/6 7/8/9读取列。

我已经有了一个脚本,它将采用一个数组并使用Write-Host以列主要的顺序将其打印出来,尽管我通过阅读Keith和Roman的作品发现了很多PowerShellish的惯用改进。但是从阅读我的印象是这是错误的方式。而不是调用Write-Host,脚本应输出对象,并让格式化器和输出器负责将正确的东西写入用户控制台。

当脚本使用Write-Host时,其输出不可捕捉;如果我将结果赋值给一个变量,我会得到一个空变量,然后将输出写入屏幕。它就像是一条直接写入/dev/tty而不是标准输出甚至标准错误的UNIX管道中间的命令。

无可否认,我可能无法用Microsoft.PowerShell.Commands.Internal.Format这个数组做很多事情。 Format-Wide,但至少它包含输出,它不会以流氓风格显示在我的屏幕上,而且我可以随时通过将阵列传递给另一个格式化器或输出器来重新创建该输出。

+0

我确定我们可以弄清楚这一点,但我没有在我面前的unix盒子。你能告诉我们它的样子吗? – Matt

+0

看看这个[问题](http://stackoverflow.com/q/4126409/323582)和答案。该脚本的最新版本是[Format-High.ps1](https://github.com/nightroman/PowerShelf/blob/master/Format-High.ps1) –

+1

@RomanKuzmin对不起,我已经花了15分钟写作功能如下。 ;-)但是你的功能看起来非常好! –

回答

3

这是一个简单的ish函数,用于设置列主要的格式。您可以在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 
     } 
    } 
} 
+0

谢谢。看到我编辑的问题。 –

+0

@MarkReed - 没问题。尝试更新的答案。 –

+0

很好,谢谢! –