powershell脚本格式表输出中的彩色单词



是否可以使用格式表仅为powershell输出的某些单词(而不是完整的行(上色。例如,这个脚本递归地扫描文件夹中的字符串,然后用格式表输出结果。

dir -r -i *.* | Select-String $args[0] |
format-table -Property @{label="Line #"; Expression={$_.LineNumber}; width=6},
Path, Line -wrap

如果能够用特定的颜色格式化我们正在搜索的单词,这样你就可以准确地看到它在网上的位置。

您可以通过管道将表导入Out-String,然后使用Write-Host-NoNewLine开关将字符串分段写入。

类似这样的东西:

filter ColorWord {
    param(
        [string] $word,
        [string] $color
    )
    $line = $_
    $index = $line.IndexOf($word, [System.StringComparison]::InvariantCultureIgnoreCase)
    while($index -ge 0){
        Write-Host $line.Substring(0,$index) -NoNewline
        Write-Host $line.Substring($index, $word.Length) -NoNewline -ForegroundColor $color
        $used = $word.Length + $index
        $remain = $line.Length - $used
        $line = $line.Substring($used, $remain)
        $index = $line.IndexOf($word, [System.StringComparison]::InvariantCultureIgnoreCase)
    }
    Write-Host $line
}
Get-Process| Format-Table| Out-String| ColorWord -word 1 -color magenta

我喜欢Rynant的方法。这里有一个替代实现,使用-split而不是IndexOf:

filter ColorWord( [string]$word, [ConsoleColor]$color ) {
    $later = $false
    $_ -split [regex]::Escape( $word ) | foreach {
      if( $later ) { Write-Host "$word" -NoNewline -ForegroundColor $color }
      else { $later = $true }
      Write-Host $_ -NoNewline
    }
    Write-Host
}

如果行以给定单词开始或结束,则Split包括空字符串,因此额外的";如果不是第一个";思维方式


编辑:根据Rynant的评论,这里有另一个同时支持简单模式和正则表达式模式的实现:

filter ColorPattern( [string]$Pattern, [ConsoleColor]$Color, [switch]$SimpleMatch ) {
  if( $SimpleMatch ) { $Pattern = [regex]::Escape( $Pattern ) }
  
  $split = $_ -split $Pattern
  $found = [regex]::Matches( $_, $Pattern, 'IgnoreCase' )
  for( $i = 0; $i -lt $split.Count; ++$i ) {
    Write-Host $split[$i] -NoNewline
    Write-Host $found[$i] -NoNewline -ForegroundColor $Color
  }
  
  Write-Host
}

以下示例的输出显示了差异:

PS> 'd00d!' | ColorPattern 'd' 'Magenta' -Simple
d00d!

PS> 'd00d!' | ColorPattern 'd' 'Magenta'
d00d!

我喜欢Ryant给出的答案。我在这里有一个修改版本,可以通过传递数组或单词和颜色来为输出中的多个单词着色。诀窍在于,您必须根据换行符将输入文本拆分为多行。

filter ColorWord2 {
param(
    [string[]] $word,
    [string[]] $color
)
$all = $_
$lines = ($_ -split 'rn')
$lines | % {
    $line = $_      
    $x = -1
    $word | % {
        $x++
        $item = $_      
        $index = $line.IndexOf($item, [System.StringComparison]::InvariantCultureIgnoreCase)                            
            while($index -ge 0){
                Write-Host $line.Substring(0,$index) -NoNewline                 
                Write-Host $line.Substring($index, $item.Length) -NoNewline -ForegroundColor $color[$x]
                $used =$item.Length + $index
                $remain = $line.Length - $used
                $line =$line.Substring($used, $remain)
                $index = $line.IndexOf($item, [System.StringComparison]::InvariantCultureIgnoreCase)
            }
        }
    Write-Host $line
} }

并将按以下执行

Get-Service | Format-Table| Out-String| ColorWord2 -word 'Running','Stopped' -color 'Green','Red'

最新更新