2

Я хотел бы запустить приложение Java на окнах, но покрасить некоторые выходные строки в разные цвета фона и переднего плана на основе соответствующего текста.

Возможно ли это с Windows PowerShell? Как бы я поступил так?

2 ответа2

1
  • Краткий ответ просто нет.

  • Длинный ответ: все возможно, но ...

К сожалению, любые операции по окраске и работе со строками в PowerShell - это королевская PITA. Причина в том, что готовые консольные терминалы Windows используют свой собственный способ ввода / вывода цвета, и не используют escape-последовательности для окрашивания.* [Смотрите примечание!] Это (AFAIK) всегда требует использования Write-Host . Таким образом , любые операции с цветом вскоре станет контрпродуктивным , поскольку они часто требуют обширной разработки Windows, чтобы работать вокруг слишком рано выхода и не будучи в состоянии легко хранить цвета в строковой переменной.

В любом случае, вот более полезное решение для выделения небезопасных настроек ExecutionPolicy . (В основном рабочая модификация ответа Антония.) Здесь он использует предустановленные критерии поиска (в виде массива), но, вероятно, может быть изменен и преобразован в правильную 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

Выход:

Наконец, если вам нужно передать другие строки, вам может понадобиться проанализировать вход $line и $_ чтобы разделить строки на строки. Поскольку сценарий предполагает, что в каждой строке есть только одно совпадение. Вот почему используется 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), который "подбирает" вывод командлета Get Help для Phrase PowerShell. даст цветной вывод для первой фразы в строке

 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'

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .