【问题标题】:Powershell MultiColored text on single line AND Centered单行和居中的 Powershell 多色文本
【发布时间】:2019-08-25 09:54:58
【问题描述】:

我有一个需要更改的 powershell 函数。该功能在终端中居中文本但是,我需要能够在一行上为文本输出多种颜色。如果我做 -NoNewLine 并做更多的 Write-host 来改变颜色......那么它仍然会计算终端的宽度,并且仍然会添加尽可能多的填充,因为它不会添加 -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 条件,我更改了填充计算,但无法正确处理。

【问题讨论】:

  • 如果您想在单行上使用多种颜色同时使复合字符串居中,您必须传递多个字符串和一个平行的颜色数组。
  • 这不是你想要的,但可以修改:stackoverflow.com/a/46046113/45375 使用嵌入在单个字符串中的着色指令。

标签: windows powershell


【解决方案1】:

PowerShell 模块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
}

【讨论】:

  • 有没有办法在没有模块的情况下完成这项工作?我希望让这个脚本开箱即用。
  • 我从 PSWriteColor 复制粘贴了一些代码。现在它应该在没有模块的情况下工作。
猜你喜欢
  • 2011-05-04
  • 1970-01-01
  • 1970-01-01
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-11
  • 2010-12-26
相关资源
最近更新 更多