我想在 Windows 上运行一个 java 应用程序,但根据匹配的文本为一些输出行涂上不同的背景和前景色。
使用 Windows powershell 可以实现吗?我该怎么做?
答案1
这短的答案很简单不。
这长的答案是一切皆有可能, 但 ...
不幸的是,任何颜色和字符串操作电源外壳非常麻烦。原因是开箱即用的 Windows 控制台终端使用自己的方式进行着色,而不是使用转义序列进行着色。* [见注释!] 这(据我所知)总是需要使用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
添加了一些色彩能力。然而,已经有几十个第三方控制台解决方案可以做到这一点。
答案2
正如下面的简单示例一样,您可以尝试匹配输出并相应地着色。
$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 检查)“grepping”Phrase PowerShell 的 Get Help cmdlet 输出。将为每行第一个短语提供彩色输出
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
{ }
# the last bracket
}
#Trace-Word -content (Get-Content iis.log) -words "IIS", 's', "exe", "10", 'system'