PowerShellでgrep出力に色を付けることは可能ですか?


2

WindowsでJavaアプリケーションを実行したいのですが、一致するテキストに基づいて、いくつかの出力行に異なる背景色と前景色を色付けします。

これはWindows PowerShellで可能ですか?それをどうやってやるの?

回答:


1
  • 短い答えは単純ですがありません

  • ロング答えはということです何でも可能ですが、...

残念ながら、PowerShellでの色付けと文字列操作は、ロイヤルPITAです。その理由は、すぐにWindowsコンソール端末がイン/アウト着色する独自の方法を使用して、着色のためのエスケープシーケンスを使用していないということです。*この(私の知る限り)常に使用する必要が[注意!を参照してください] Write-Host。そのため、多くの場合、広範なWindows エンジニアリングが必要になるため、色操作はすぐに非生産的になり、早すぎる出力を回避し、文字列変数に色を簡単に保存できません。

いずれにせよ、安全でない ExecutionPolicy設定を強調するためのより便利な解決策がここにあります。(基本的には、Antonyの答えの実用的な修正です。)ここでは、事前設定された検索条件(配列として)を使用していますが、おそらく修正して適切なColorGrep(<string>)関数に変換できます。

# To get the ExecutionPolicy List
Function Get-MyPolicy {
    $ZZ_EPOL = ((Get-ExecutionPolicy -List) | Format-Table -hideTableHeader @{Label="ExePol"; e={"        {0,-16}: {1,-20}" -f $_.Scope, $_.ExecutionPolicy}})
    $ZZ_EPOL
}

# Colorize the unsafe Execution Policies
Function ColorMatch {
    Process {
        $polkeys = @("Bypass","Unrestricted")
        foreach ($line in $_) {
            foreach ($i in $polkeys) {
                $res =''
                If ($line -match $i) {
                    $iPosition  = $line.IndexOf($i)         # start position of "grep phrase"
                    $iLength    = $i.Length                 # length of grep phrase
                    $iEnd       = $iPosition + $iLength     # end of grep phrase
                    $LineLength = $line.Length              # length of line
                    $iComplete  = $LineLength - $iEnd       # length of characters to complete the line

                    $res  = (Write-Host $line.Substring(0, $iPosition) -NoNewline)
                    $res += (Write-Host $line.Substring($iPosition, $iLength) -ForegroundColor Red -NoNewline)
                    $res += (Write-Host $line.Substring($iEnd, $iComplete) -NoNewline)
                    Write-Host $res
                    break  # There's only one match per line
                }
            } # END foreach 2
            If (($res -eq '') -and ($line -ne '')) { 
                Write-Host $line 
            } 
        } # END foreach 1
    } # END process
}

これを実行するには、次を使用します。
Get-MyPolicy | Out-String -stream | ColorMatch

出力は次のとおりです。

ここに画像の説明を入力してください

最後に、他の文字列を渡す必要がある場合、文字列を行に分割するために$lineand $_入力を解析する必要があるかもしれません。スクリプトは1行に1つの一致しかないことを前提としているため。それがOut-String使用される理由です。

注:
最近Windows 10カラー機能が追加されました。ただし、すでにこれを実行しているサードパーティ製のコンソールソリューションは多数あります。


1

以下の簡単な例のように、出力とカラーリングを一致させてみてください。

$Items = @("Find","Matching","Item")
$colItem = "Matching"

foreach ($i in $Items) {

    if ($i -match $colItem){
      write-host  $i -foregroundcolor magenta -BackgroundColor yellow}
     else {write-host $i}
}

-編集-

大まかな作業例(ps4でのみチェック)でさらに詳しく説明します。PhrasePowerShellのヘルプヘルプコマンドレット出力を "grepping"します。行ごとの最初のフレーズの色付き出力を提供します

 Function Coloured-Output {
    Process { 
       $i = "PowerShell"
       If ($_ -match $i){
          $iPosition = $_.IndexOf($i)       # start position of "grep phrase"
          $iLength = $i.Length              # length of grep phrase
          $iEnd = $iPosition + $iLength     # end of grep phrase
          $LineLength = $_.Length           # length of line
          $iComplete = $LineLength - $iEnd  # length of characters to complete the line
          Write-Host $_.Substring(0,$iPosition) -NoNewline
          Write-Host $_.Substring($iPosition,$iLength) -Foregroundcolor Blue -BackgroundColor cyan -NoNewline
          Write-Host $_.Substring($iEnd,$iComplete)
       }
       else {write-host $_ }
    } # End of Process
} # End of Function

$SplitThis = Get-Help

   $SplitThis -split ("`n")  | Out-String -stream | Coloured-Output

##########編集者による最適なソリューション############

最高のソリューションhttps://ridicurious.com/2018/03/14/highlight-words-in-powershell-console/これは、私自身の解決策よりも、元の質問に対するはるかに優れた包括的な答えです。

    Function Trace-Word
{
    [Cmdletbinding()]
    [Alias("Highlight")]
    Param(
            [Parameter(ValueFromPipeline=$true, Position=0)] [string[]] $content,
            [Parameter(Position=1)] 
            [ValidateNotNull()]
            [String[]] $words = $(throw "Provide word[s] to be highlighted!")
    )

Begin
{

    $Color = @{       
                0='Yellow'      
                1='Magenta'     
                2='Red'         
                3='Cyan'        
                4='Green'       
                5 ='Blue'        
                6 ='DarkGray'    
                7 ='Gray'        
                8 ='DarkYellow'    
                9 ='DarkMagenta'    
                10='DarkRed'     
                11='DarkCyan'    
                12='DarkGreen'    
                13='DarkBlue'        
    }

    $ColorLookup =@{}

    For($i=0;$i -lt $words.count ;$i++)
    {
        if($i -eq 13)
        {
            $j =0
        }
        else
        {
            $j = $i
        }

        $ColorLookup.Add($words[$i],$Color[$j])
        $j++
    }

}
Process
{
$content | ForEach-Object {

    $TotalLength = 0

    $_.split() | `
    Where-Object {-not [string]::IsNullOrWhiteSpace($_)} | ` #Filter-out whiteSpaces
    ForEach-Object{
                    if($TotalLength -lt ($Host.ui.RawUI.BufferSize.Width-10))
                    {
                        #"TotalLength : $TotalLength"
                        $Token =  $_
                        $displayed= $False

                        Foreach($Word in $Words)
                        {
                            if($Token -like "*$Word*")
                            {
                                $Before, $after = $Token -Split "$Word"


                                #"[$Before][$Word][$After]{$Token}`n"

                                Write-Host $Before -NoNewline ; 
                                Write-Host $Word -NoNewline -Fore Black -Back $ColorLookup[$Word];
                                Write-Host $after -NoNewline ; 
                                $displayed = $true                                   
                                #Start-Sleep -Seconds 1    
                                #break  
                            }

                        } 
                        If(-not $displayed)
                        {   
                            Write-Host "$Token " -NoNewline                                    
                        }
                        else
                        {
                            Write-Host " " -NoNewline  
                        }
                        $TotalLength = $TotalLength + $Token.Length  + 1
                    }
                    else
                    {                      
                        Write-Host '' #New Line  
                        $TotalLength = 0 

                    }

                        #Start-Sleep -Seconds 0.5

    }
    Write-Host '' #New Line               
}
}
end
{    }

}

#Trace-Word -content (Get-Content iis.log) -words "IIS", 's', "exe", "10", 'system'

残念ながら、その関数は「PowerShell」の最初の出現とのみ一致します。
not2qubit

@ not2qubitは、各行に不足している分割を追加し、現在は行ごとに最初のオカレンスのみを追加しました。
アントニー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.