我需要更改Powershell功能。该功能使文本在终端中居中,但是,我需要能够在一行上输出多种颜色的文本。如果我执行-NoNewLine并执行更多写入主机操作以更改颜色...,那么它仍会计算终端的宽度,并且仍会添加与不添加-NoNewLine一样多的填充。本质上,我希望文本居中,并且希望能够使用多种颜色。我所拥有的我每行只能做一种颜色。
function WriteCentered([String] $text, $color = $null)
{
$width = [int](Get-Host).UI.RawUI.BufferSize.Width
$twidth = [int]$text.Length
$offset = ($width / 2) - ($twidth / 2)
$newText = $text.PadLeft($offset + $twidth)
if($color)
{
Write-Host $newText -ForegroundColor $color
}
else
{
Write-Host $newText
}
}
我添加了更多的IF条件,更改了填充计算,但无法正确设置它。
答案 0 :(得分:1)
PowerShell-Module PSWriteColor在一行上输出多种颜色方面已经做得很好。您可以直接从GitHub下载并使用Import-Module <PATH-TO>\PSWriteColor.psd1
导入它,也可以直接使用Install-Module -Name PSWriteColor
从PowerShell库安装它。
简而言之语法为Write-Color -Text "GreenText","RedText","BlueText" -Color Green,Red,Blue
。因此,我们需要在[String[]]$Text
参数前面加上一个包含必要空格的字符串,以便将消息在屏幕上居中,并在[ConsoleColor[]]$Color
参数上加上相应的颜色。
这里有一些用于居中的辅助功能。
#Requires -Modules @{ ModuleName="PSWriteColor"; ModuleVersion="0.8.5" }
function WriteColor-Centered {
param(
[Parameter(Mandatory=$true)][string[]]$Text,
[Parameter(Mandatory=$true)][ConsoleColor[]]$Color
)
$messageLength = 0
$Text | ForEach-Object { $messageLength += $_.Length }
[String[]] $centeredText = "{0}" -f (' ' * (([Math]::Max(0, $Host.UI.RawUI.BufferSize.Width / 2) - [Math]::Floor($messageLength / 2))))
$centeredText += $Text
[ConsoleColor[]]$OutColor = @([ConsoleColor]::White)
$OutColor += $Color
Write-Color -Text $centeredText -Color $OutColor
# Alt.: use WriteColor-Core, see below
# WriteColor-Core -Text $centeredText -Color $OutColor
}
我从this stackoverflow answer复制了空格计算。
编辑:有人问我是否有可能在不导入模块的情况下完成这项工作。老实说,我现在有点脏了,因为我进入了一个编写良好的模块的源代码,剥离了所有功能和错误处理,并将其粘贴到这里。
无论如何-如果您在上面的包装函数中替换了Write-Color
的调用并调用了以下WriteColor-Core
,则可以省去加载PSWriteColor模块。
function WriteColor-Core {
param(
[Parameter(Mandatory=$true)][string[]]$Text,
[Parameter(Mandatory=$true)][ConsoleColor[]]$Color
)
# Fallback defaults if one of the values isn't set
$LastForegroundColor = [console]::ForegroundColor
# The real deal coloring
for ($i = 0; $i -lt $Text.Count; $i++) {
$CurrentFGColor = if ($Color[$i]) { $Color[$i] } else { $LastForegroundColor }
$WriteParams = @{
NoNewLine = $true
ForegroundColor = $CurrentFGColor
}
Write-Host $Text[$i] @WriteParams
# Store last color set, in case next iteration doesn't have a set color
$LastForegroundColor = $CurrentFGColor
}
Write-Host
}