如何在Windows终端中更改文本颜色

目录

介绍

终端颜色

使用代码

辅助函数

处理对比度

有趣的点


介绍

终端的默认文本输出是单色的,并且不提供提供上下文的简单方法。例如,您可能希望错误以红色显示,成功以绿色显示,或者重要信息以粗体显示。

为终端输出添加颜色很简单,涉及在文本之前输出正确的控制字符。

这是一篇关于如何在Linux终端中更改文本颜色的配套文章 

终端颜色

要输出彩色文本,您需要echo控制字符以获得所需的颜色,然后输出文本,然后(为了整洁)将输出重置为默认值。下表列出了代码

颜色

前景

背景

Default

ESC[39m

ESC[49m

Black

ESC[30m

ESC[40m

Dark red

ESC[31m

ESC[41m

Dark green

ESC[32m

ESC[42m

Dark yellow (Orange-ish)

ESC[33m

ESC[43m

Dark blue

ESC[34m

ESC[44m

Dark magenta

ESC[35m

ESC[45m

Dark cyan

ESC[36m

ESC[46m

Light gray

ESC[37m

ESC[47m

Dark gray

ESC[90m

ESC[100m

Red

ESC[91m

ESC[101m

Green

ESC[92m

ESC[101m

Orange

ESC[93m

ESC[103m

Blue

ESC[94m

ESC[104m

Magenta

ESC[95m

ESC[105m

Cyan

ESC[96m

ESC[106m

White

ESC[97m

ESC[107m

并且重置代码是ESC [0m其中ESC 是转义码。

前景色字符串的格式为:

"ESC[" + "<0 or 1, meaning normal or bold>;" + "<color code> + "m"

而背景的格式为:

"ESC[" + "<color code>" + "m"

这些代码可以一起输出,以便同时更改前景色和背景色。

使用代码

在输出颜色代码之前,您需要生成ESC序列。这样做可能是最简单的,然后将其存储起来以备后用:

:: Sets up the ESC string for use later in this script
:setESC
    for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
      set ESC=%%b
      exit /B 0
    )
    exit /B 0

这将设置一个具有正确顺序的ESC变量 

输出红色文本的简单示例

setlocal enabledelayedexpansion
call :setESC
echo !ESC![91mThis is red text!ESC![0m

在白色背景上输出红色文本的示例

setlocal enabledelayedexpansion
call :setESC
echo !ESC![91m!ESC![107mThis is red text on a white background!ESC![0m"

这有点麻烦,所以我创建了一些简单的子例程,它们提供了以更文明的方式输出文本的方法

辅助函数

以下辅助函数允许您执行以下操作

call :WriteLine "This is red text" "Red"
call :WriteLine "This is red text on a white background" "Red" "White"

容易得多。

REM  Set to false if you find your environment just doesn't handle colors well
set useColor=true


:: Sets up the ESC string for use later in this script
:setESC
    for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
      set ESC=%%b
      exit /B 0
    )
    exit /B 0

:: Sets the currentColor global for the given foreground/background colors
:: currentColor must be output to the terminal before outputing text in
:: order to generate a colored output.
::
:: string foreground color name. Optional if no background provided.
::        Defaults to "White"
:: string background color name.  Optional. Defaults to Black.
:setColor

    REM If you want to get a little fancy then you can also try
    REM  - %ESC%[4m - Underline
    REM  - %ESC%[7m - Inverse

    set foreground=%~1
    set background=%~2

    if "!foreground!"=="" set foreground=White
    if /i "!foreground!"=="Default" set foreground=White
    if "!background!"=="" set background=Black
    if /i "!background!"=="Default" set background=Black

    if "!ESC!"=="" call :setESC

    REM This requires the setContrastForeground subroutine, which is discussed below
    if /i "!foreground!"=="Contrast" (
        call :setContrastForeground !background!
        set foreground=!contrastForeground!
    )

    set currentColor=

    REM Foreground Colours
    if /i "!foreground!"=="Black"       set currentColor=!ESC![30m
    if /i "!foreground!"=="DarkRed"     set currentColor=!ESC![31m
    if /i "!foreground!"=="DarkGreen"   set currentColor=!ESC![32m
    if /i "!foreground!"=="DarkYellow"  set currentColor=!ESC![33m
    if /i "!foreground!"=="DarkBlue"    set currentColor=!ESC![34m
    if /i "!foreground!"=="DarkMagenta" set currentColor=!ESC![35m
    if /i "!foreground!"=="DarkCyan"    set currentColor=!ESC![36m
    if /i "!foreground!"=="Gray"        set currentColor=!ESC![37m
    if /i "!foreground!"=="DarkGray"    set currentColor=!ESC![90m
    if /i "!foreground!"=="Red"         set currentColor=!ESC![91m
    if /i "!foreground!"=="Green"       set currentColor=!ESC![92m
    if /i "!foreground!"=="Yellow"      set currentColor=!ESC![93m
    if /i "!foreground!"=="Blue"        set currentColor=!ESC![94m
    if /i "!foreground!"=="Magenta"     set currentColor=!ESC![95m
    if /i "!foreground!"=="Cyan"        set currentColor=!ESC![96m
    if /i "!foreground!"=="White"       set currentColor=!ESC![97m
    if "!currentColor!"=="" set currentColor=!ESC![97m
    
    if /i "!background!"=="Black"       set currentColor=!currentColor!!ESC![40m
    if /i "!background!"=="DarkRed"     set currentColor=!currentColor!!ESC![41m
    if /i "!background!"=="DarkGreen"   set currentColor=!currentColor!!ESC![42m
    if /i "!background!"=="DarkYellow"  set currentColor=!currentColor!!ESC![43m
    if /i "!background!"=="DarkBlue"    set currentColor=!currentColor!!ESC![44m
    if /i "!background!"=="DarkMagenta" set currentColor=!currentColor!!ESC![45m
    if /i "!background!"=="DarkCyan"    set currentColor=!currentColor!!ESC![46m
    if /i "!background!"=="Gray"        set currentColor=!currentColor!!ESC![47m
    if /i "!background!"=="DarkGray"    set currentColor=!currentColor!!ESC![100m
    if /i "!background!"=="Red"         set currentColor=!currentColor!!ESC![101m
    if /i "!background!"=="Green"       set currentColor=!currentColor!!ESC![102m
    if /i "!background!"=="Yellow"      set currentColor=!currentColor!!ESC![103m
    if /i "!background!"=="Blue"        set currentColor=!currentColor!!ESC![104m
    if /i "!background!"=="Magenta"     set currentColor=!currentColor!!ESC![105m
    if /i "!background!"=="Cyan"        set currentColor=!currentColor!!ESC![106m
    if /i "!background!"=="White"       set currentColor=!currentColor!!ESC![107m

    exit /B 0

:: Outputs a line, including linefeed, to the terminal using the given foreground / background
:: colors 
::
:: string The text to output. Optional if no foreground provided. Default is just a line feed.
:: string Foreground color name. Optional if no background provided. Defaults to "White"
:: string Background color name. Optional. Defaults to "Black"
:WriteLine
    SetLocal EnableDelayedExpansion
    
    if "!ESC!"=="" call :setESC    
    set resetColor=!ESC![0m

    set str=%~1

    if "!str!"=="" (
        echo:
        exit /b 0
    )
    if "!str: =!"=="" (
        echo:
        exit /b 0
    )

    if /i "%useColor%"=="true" (
        call :setColor %2 %3
        echo !currentColor!!str!!resetColor!
    ) else (
        echo !str!
    )
    exit /b 0

:: Outputs a line without a linefeed to the terminal using the given foreground / background colors 
::
:: string The text to output. Optional if no foreground provided. Default is just a line feed.
:: string Foreground color name. Optional if no background provided. Defaults to "White"
:: string Background color name. Optional. Defaults to "Black"
:Write
    SetLocal EnableDelayedExpansion
    
    if "!ESC!"=="" call :setESC
    set resetColor=!ESC![0m

    set str=%~1

    if "!str!"=="" exit /b 0
    if "!str: =!"=="" exit /b 0

    if /i "%useColor%"=="true" (
        call :setColor %2 %3
        <NUL set /p =!currentColor!!str!!resetColor!
    ) else (
        <NUL set /p =!str!
    )
    exit /b 0

处理对比度

假设我们已经定义了一组预定义的颜色,并且我们希望使用它们来确保一致性 

set color_primary=Blue
set color_mute=Gray
set color_info=Yellow
set color_success=Green
set color_warn=DarkYellow
set color_error=Red

如果我们使用这些作为背景颜色输出文本,我们会得到

call :WriteLine
call :WriteLine "Default color on predefined background"
call :WriteLine

call :WriteLine "  Default colored background" "Default"
call :WriteLine "  Primary colored background" "Default" %color_primary%
call :WriteLine "  Mute colored background"    "Default" %color_mute%
call :WriteLine "  Info colored background"    "Default" %color_info%
call :WriteLine "  Success colored background" "Default" %color_success%
call :WriteLine "  Warning colored background" "Default" %color_warn%
call :WriteLine "  Error colored background"   "Default" %color_error%

事情有点模糊,所以让我们再添加一个函数,它将在我们选择的任何背景上提供对比鲜明的前景

:: Sets the name of a color that will providing a contrasting foreground
:: color for the given background color.
::
:: string background color name. 
:: on return, contrastForeground will be set
:setContrastForeground

    set background=%~1

    if "!background!"=="" background=Black

    if /i "!background!"=="Black"       set contrastForeground=White
    if /i "!background!"=="DarkRed"     set contrastForeground=White
    if /i "!background!"=="DarkGreen"   set contrastForeground=White
    if /i "!background!"=="DarkYellow"  set contrastForeground=White
    if /i "!background!"=="DarkBlue"    set contrastForeground=White
    if /i "!background!"=="DarkMagenta" set contrastForeground=White
    if /i "!background!"=="DarkCyan"    set contrastForeground=White
    if /i "!background!"=="Gray"        set contrastForeground=Black
    if /i "!background!"=="DarkGray"    set contrastForeground=White
    if /i "!background!"=="Red"         set contrastForeground=White
    if /i "!background!"=="Green"       set contrastForeground=White
    if /i "!background!"=="Yellow"      set contrastForeground=Black
    if /i "!background!"=="Blue"        set contrastForeground=White
    if /i "!background!"=="Magenta"     set contrastForeground=White
    if /i "!background!"=="Cyan"        set contrastForeground=Black
    if /i "!background!"=="White"       set contrastForeground=Black

    exit /B 0

我们已经在Write方法中将其连接起来:如果前景色设置为对比度,那么前景色将被视为与给定背景具有良好对比度的东西。

使用我们只需做

call :WriteLine "  Primary colored background" "Contrast" %color_primary%
call :WriteLine "  Mute colored background"    "Contrast" %color_mute%
call :WriteLine "  Info colored background"    "Contrast" %color_info%
call :WriteLine "  Success colored background" "Contrast" %color_success%
call :WriteLine "  Warning colored background" "Contrast" %color_warn%
call :WriteLine "  Error colored background"   "Contrast" %color_error%

有趣的点

其中的一个挑战是通过没有换行符的CMD shell输出文本。echo命令默认添加换行符。要在CMD脚本中输出文本而不包含换行符,只需使用

<NUL set /p ="My string goes here"

https://www.codeproject.com/Articles/5329269/How-to-change-text-color-in-a-Windows-terminal

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值