Я хотел бы запустить приложение Java на окнах, но покрасить некоторые выходные строки в разные цвета фона и переднего плана на основе соответствующего текста.
Возможно ли это с Windows PowerShell? Как бы я поступил так?
Я хотел бы запустить приложение Java на окнах, но покрасить некоторые выходные строки в разные цвета фона и переднего плана на основе соответствующего текста.
Возможно ли это с Windows PowerShell? Как бы я поступил так?
Краткий ответ просто нет.
Длинный ответ: все возможно, но ...
К сожалению, любые операции по окраске и работе со строками в 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
добавлены некоторые цветовые возможности. Тем не менее, существуют десятки сторонних консольных решений, которые уже делают это.
Как и в моем простом примере, приведенном ниже, вы можете попытаться сопоставить свой результат и цвет соответственно.
$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'