280

我知道该color bf命令设置了整个命令行窗口的颜色,但我想用不同的颜色打印一行。

4

28 回答 28

370

我想用不同的颜色打印一行。

使用 ANSI 转义序列。

10 之前的 Windows - 控制台上不支持 ANSI 颜色

对于低于 10 的 Windows 版本,Windows 命令控制台默认不支持输出着色。您可以安装CmderConEmuANSICONMintty(在 GitBash 和 Cygwin 中默认使用)来为您的 Windows 命令控制台添加着色支持。

Windows 10 - 命令行颜色

从 Windows 10 开始,Windows 控制台默认支持 ANSI 转义序列和一些颜色。该功能在 2015 年 11 月随 Threshold 2 更新一起提供。

MSDN 文档

更新(05-2019):ColorTool使您能够更改控制台的配色方案。它是 Microsoft终端项目的一部分。

演示

在此处输入图像描述

批处理命令

Michele Locatiwin10colors.cmd撰写:

下面的文本被去除了特殊字符,将不起作用。您必须从这里复制它。

@echo off
cls
echo [101;93m STYLES [0m
echo ^<ESC^>[0m [0mReset[0m
echo ^<ESC^>[1m [1mBold[0m
echo ^<ESC^>[4m [4mUnderline[0m
echo ^<ESC^>[7m [7mInverse[0m
echo.
echo [101;93m NORMAL FOREGROUND COLORS [0m
echo ^<ESC^>[30m [30mBlack[0m (black)
echo ^<ESC^>[31m [31mRed[0m
echo ^<ESC^>[32m [32mGreen[0m
echo ^<ESC^>[33m [33mYellow[0m
echo ^<ESC^>[34m [34mBlue[0m
echo ^<ESC^>[35m [35mMagenta[0m
echo ^<ESC^>[36m [36mCyan[0m
echo ^<ESC^>[37m [37mWhite[0m
echo.
echo [101;93m NORMAL BACKGROUND COLORS [0m
echo ^<ESC^>[40m [40mBlack[0m
echo ^<ESC^>[41m [41mRed[0m
echo ^<ESC^>[42m [42mGreen[0m
echo ^<ESC^>[43m [43mYellow[0m
echo ^<ESC^>[44m [44mBlue[0m
echo ^<ESC^>[45m [45mMagenta[0m
echo ^<ESC^>[46m [46mCyan[0m
echo ^<ESC^>[47m [47mWhite[0m (white)
echo.
echo [101;93m STRONG FOREGROUND COLORS [0m
echo ^<ESC^>[90m [90mWhite[0m
echo ^<ESC^>[91m [91mRed[0m
echo ^<ESC^>[92m [92mGreen[0m
echo ^<ESC^>[93m [93mYellow[0m
echo ^<ESC^>[94m [94mBlue[0m
echo ^<ESC^>[95m [95mMagenta[0m
echo ^<ESC^>[96m [96mCyan[0m
echo ^<ESC^>[97m [97mWhite[0m
echo.
echo [101;93m STRONG BACKGROUND COLORS [0m
echo ^<ESC^>[100m [100mBlack[0m
echo ^<ESC^>[101m [101mRed[0m
echo ^<ESC^>[102m [102mGreen[0m
echo ^<ESC^>[103m [103mYellow[0m
echo ^<ESC^>[104m [104mBlue[0m
echo ^<ESC^>[105m [105mMagenta[0m
echo ^<ESC^>[106m [106mCyan[0m
echo ^<ESC^>[107m [107mWhite[0m
echo.
echo [101;93m COMBINATIONS [0m
echo ^<ESC^>[31m                     [31mred foreground color[0m
echo ^<ESC^>[7m                      [7minverse foreground ^<-^> background[0m
echo ^<ESC^>[7;31m                   [7;31minverse red foreground color[0m
echo ^<ESC^>[7m and nested ^<ESC^>[31m [7mbefore [31mnested[0m
echo ^<ESC^>[31m and nested ^<ESC^>[7m [31mbefore [7mnested[0m
于 2016-07-27T15:22:24.080 回答
58

这不是一个很好的答案,但如果你知道目标工作站有 Powershell,你可以做这样的事情(假设 BAT / CMD 脚本):

CALL:ECHORED "Print me in red!"

:ECHORED
%Windir%\System32\WindowsPowerShell\v1.0\Powershell.exe write-host -foregroundcolor Red %1
goto:eof

编辑:(现在更简单了!)

这是一个旧答案,但我想我会澄清一下并简化一下

图像

PowerShell现在包含在自 7 以来的所有 Windows 版本中。因此,此答案的语法可以缩短为更简单的形式:

  • 不需要指定路径,因为它应该已经在环境变量中
  • 明确的命令可以缩写。例如,您可以:
    • 使用-fore而不是-foregroundcolor
    • 使用-back而不是-backgroundcolor
  • 该命令基本上也可以使用' inline '代替echo
    (而不是像上面那样创建单独的批处理文件)。

例子:

powershell write-host -fore Cyan This is Cyan text
powershell write-host -back Red This is Red background

更多信息:

完整的颜色列表和更多信息可在
- PowerShell文档中找到Write-Host

于 2011-08-04T13:30:02.763 回答
58

这是一个自编译的bat/.net 混合体(应该另存为.BAT),可以在任何安装了 .net 框架的系统上使用(即使对于最古老的 XP/2003 来说,看到没有 .NET 框架的窗口也是罕见的安装)。它使用 jscript.net 编译器创建一个 exe,该 exe 能够仅为当前行打印具有不同背景/前景颜色的字符串。

@if (@X)==(@Y) @end /* JScript comment
@echo off
setlocal

for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*jsc.exe"') do (
   set "jsc=%%v"
)

if not exist "%~n0.exe" (
    "%jsc%" /nologo /out:"%~n0.exe" "%~dpsfnx0"
)

%~n0.exe %*

endlocal & exit /b %errorlevel%

*/

import System;

var arguments:String[] = Environment.GetCommandLineArgs();

var newLine = false;
var output = "";
var foregroundColor = Console.ForegroundColor;
var backgroundColor = Console.BackgroundColor;
var evaluate = false;
var currentBackground=Console.BackgroundColor;
var currentForeground=Console.ForegroundColor;


//http://stackoverflow.com/a/24294348/388389
var jsEscapes = {
  'n': '\n',
  'r': '\r',
  't': '\t',
  'f': '\f',
  'v': '\v',
  'b': '\b'
};

function decodeJsEscape(_, hex0, hex1, octal, other) {
  var hex = hex0 || hex1;
  if (hex) { return String.fromCharCode(parseInt(hex, 16)); }
  if (octal) { return String.fromCharCode(parseInt(octal, 8)); }
  return jsEscapes[other] || other;
}

function decodeJsString(s) {
  return s.replace(
      // Matches an escape sequence with UTF-16 in group 1, single byte hex in group 2,
      // octal in group 3, and arbitrary other single-character escapes in group 4.
      /\\(?:u([0-9A-Fa-f]{4})|x([0-9A-Fa-f]{2})|([0-3][0-7]{0,2}|[4-7][0-7]?)|(.))/g,
      decodeJsEscape);
}


function printHelp( ) {
   print( arguments[0] + "  -s string [-f foreground] [-b background] [-n] [-e]" );
   print( " " );
   print( " string          String to be printed" );
   print( " foreground      Foreground color - a " );
   print( "                 number between 0 and 15." );
   print( " background      Background color - a " );
   print( "                 number between 0 and 15." );
   print( " -n              Indicates if a new line should" );
   print( "                 be written at the end of the ");
   print( "                 string(by default - no)." );
   print( " -e              Evaluates special character " );
   print( "                 sequences like \\n\\b\\r and etc ");
   print( "" );
   print( "Colors :" );
   for ( var c = 0 ; c < 16 ; c++ ) {
        
        Console.BackgroundColor = c;
        Console.Write( " " );
        Console.BackgroundColor=currentBackground;
        Console.Write( "-"+c );
        Console.WriteLine( "" );
   }
   Console.BackgroundColor=currentBackground;
   
   

}

function errorChecker( e:Error ) {
        if ( e.message == "Input string was not in a correct format." ) {
            print( "the color parameters should be numbers between 0 and 15" );
            Environment.Exit( 1 );
        } else if (e.message == "Index was outside the bounds of the array.") {
            print( "invalid arguments" );
            Environment.Exit( 2 );
        } else {
            print ( "Error Message: " + e.message );
            print ( "Error Code: " + ( e.number & 0xFFFF ) );
            print ( "Error Name: " + e.name );
            Environment.Exit( 666 );
        }
}

function numberChecker( i:Int32 ){
    if( i > 15 || i < 0 ) {
        print("the color parameters should be numbers between 0 and 15");
        Environment.Exit(1);
    }
}


if ( arguments.length == 1 || arguments[1].toLowerCase() == "-help" || arguments[1].toLowerCase() == "-help"   ) {
    printHelp();
    Environment.Exit(0);
}

for (var arg = 1; arg <= arguments.length-1; arg++ ) {
    if ( arguments[arg].toLowerCase() == "-n" ) {
        newLine=true;
    }
    
    if ( arguments[arg].toLowerCase() == "-e" ) {
        evaluate=true;
    }
    
    if ( arguments[arg].toLowerCase() == "-s" ) {
        output=arguments[arg+1];
    }
    
    
    if ( arguments[arg].toLowerCase() == "-b" ) {
        
        try {
            backgroundColor=Int32.Parse( arguments[arg+1] );
        } catch(e) {
            errorChecker(e);
        }
    }
    
    if ( arguments[arg].toLowerCase() == "-f" ) {
        try {
            foregroundColor=Int32.Parse(arguments[arg+1]);
        } catch(e) {
            errorChecker(e);
        }
    }
}

Console.BackgroundColor = backgroundColor ;
Console.ForegroundColor = foregroundColor ;

if ( evaluate ) {
    output=decodeJsString(output);
}

if ( newLine ) {
    Console.WriteLine(output);  
} else {
    Console.Write(output);
    
}

Console.BackgroundColor = currentBackground;
Console.ForegroundColor = currentForeground;

这是帮助消息:

在此处输入图像描述

示例

coloroutput.bat -s "aa\nbb\n\u0025cc" -b 10 -f 3 -n -e

您还可以在此处找到此脚本。

您还可以查看卡洛斯的颜色功能-> http://www.dostips.com/forum/viewtopic.php?f=3&t=4453

于 2015-01-31T10:53:09.670 回答
42

Windows 10 - TH2 及更高版本:

(又名版本 1511,内部版本 10586,发布 2015-11-10)

在命令提示符下:

echo ^[[32m HI ^[[0m

使用实际键:echo Ctrl++[[32m HI Ctrl[[0mEnter

您应该在其下方看到一个绿色的“HI”。

代码编号可以在这里找到:

记事本:

要将其保存到记事本中,您可以使用以下命令在其中键入 ESC:Alt+027与数字键盘,然后是[32m部件。当我在笔记本电脑上时的另一个技巧,将上面的行重定向到一个文件中以开始,然后剪切并粘贴:

echo echo ^[[32m HI ^[[0m >> batch_file.cmd
于 2018-10-05T20:06:12.347 回答
19

您可以只创建具有要打印的单词名称的文件,使用可以彩色打印的 findstr,然后擦除文件。试试这个例子:

@echo off
SETLOCAL EnableDelayedExpansion
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
  set "DEL=%%a"
)

call :ColorText 0a "green"
call :ColorText 0C "red"
call :ColorText 0b "cyan"
echo(
call :ColorText 19 "blue"
call :ColorText 2F "white"
call :ColorText 4e "yellow"

goto :eof

:ColorText
echo off
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1
goto :eof

运行color /?以获取颜色列表。

于 2014-04-15T00:09:45.197 回答
15

您可以使用ANSICON在旧版本的 Windows 中启用 ANSI 终端代码。我在 Windows XP 和 Windows 7 中使用过 32 位和 64 位版本。

于 2012-01-19T03:49:27.160 回答
6

我也对 cmd 中缺乏适当的着色感到恼火,所以我继续创建了cmdcolor。它只是一个标准输出代理,它查找一组有限的 ANSI/VT100 控制序列(换句话说,就像在 bash 中一样),即echo \033[31m RED \033[0m DEFAULT | cmdcolor.exe.

使用和下载

于 2014-02-13T11:59:34.763 回答
6

我看这个是因为我想在 Win7 批处理文件中引入一些简单的文本颜色。这就是我想出的。谢谢你的帮助。

@echo off
cls && color 08

rem .... the following line creates a [DEL] [ASCII 8] [Backspace] character to use later
rem .... All this to remove [:]
for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")

echo.

<nul set /p="("
call :PainText 09 "BLUE is cold"    && <nul set /p=")  ("
call :PainText 02 "GREEN is earth"  && <nul set /p=")  ("
call :PainText F0 "BLACK is night"  && <nul set /p=")"
echo.
<nul set /p="("
call :PainText 04 "RED is blood"    && <nul set /p=")  ("
call :PainText 0e "YELLOW is pee"   && <nul set /p=")  ("
call :PainText 0F "WHITE all colors"&& <nul set /p=")"

goto :end

:PainText
<nul set /p "=%DEL%" > "%~2"
findstr /v /a:%1 /R "+" "%~2" nul
del "%~2" > nul
goto :eof

:end
echo.
pause
于 2015-02-09T05:00:46.197 回答
5

已经有超过 250 个赞成票的公认答案。我仍在贡献的原因是,escape许多编辑器(我正在使用,例如 MS Code)不接受回显所需的字符,并且所有其他解决方案都需要一些第三方(非 Windows 默认)软件。

仅使用普通批处理命令的解决方法是使用PROMPT而不是ECHO. 该PROMPT命令escape以任何编辑器友好的方式接受字符作为$E字符序列。(只需将EscASCII转义码中的)替换为$E.

这是一个演示代码:

@ECHO OFF

    :: Do not pollute environment with the %prompt.bak% variable
    :: ! forgetting ENDLOCAL at the end of the batch leads to prompt corruption
    SETLOCAL

    :: Old prompt settings backup
    SET prompt.bak=%PROMPT%

    :: Entering the "ECHO"-like section

        :: Forcing prompt to display after every command (see below)
        ECHO ON

        :: Setting the prompt using the ANSI Escape sequence(s)
        :: - Always start with $E[1A, otherwise the text would appear on a next line
        :: - Then the decorated text follows
        :: - And it all ends with $E30;40m, which makes the following command invisible
        ::   - assuming default background color of the screen
        @ PROMPT $E[1A$E[30;42mHELLO$E[30;40m

        :: An "empty" command that forces the prompt to display. 
        :: The word "rem" is displayed along with the prompt text but is made invisible
        rem

        :: Just another text to display
        @ PROMPT $E[1A$E[33;41mWORLD$E[30;40m
        rem

        :: Leaving the "ECHO"-like section
        @ECHO OFF

    :: Or a more readable version utilizing the cursor manipulation ASCII ESC sequences

        :: the initial sequence
        PROMPT $E[1A
        :: formating commands
        PROMPT %PROMPT%$E[32;44m
        :: the text
        PROMPT %PROMPT%This is an "ECHO"ed text...
        :: new line; 2000 is to move to the left "a lot"
        PROMPT %PROMPT%$E[1B$E[2000D
        :: formating commands fro the next line
        PROMPT %PROMPT%$E[33;47m
        :: the text (new line)
        PROMPT %PROMPT%...spreading over two lines
        :: the closing sequence
        PROMPT %PROMPT%$E[30;40m

        :: Looks like this without the intermediate comments:
        :: PROMPT $E[1A
        :: PROMPT %PROMPT%$E[32;44m
        :: PROMPT %PROMPT%This is an "ECHO"ed text...
        :: PROMPT %PROMPT%$E[1B$E[2000D
        :: PROMPT %PROMPT%$E[33;47m
        :: PROMPT %PROMPT%...spreading over two lines
        :: PROMPT %PROMPT%$E[30;40m

        :: show it all at once!
        ECHO ON
        rem
        @ECHO OFF

    :: End of "ECHO"-ing

    :: Setting prompt back to its original value
    :: - We prepend the settings with $E[37;40m in case
    ::   the original prompt settings do not specify color
    ::   (as they don't by default).
    :: - If they do, the $E[37;40m will become overridden, anyway.
    :: ! It is important to write this command 
    ::   as it is with `ENDLOCAL` and in the `&` form.
    ENDLOCAL & PROMPT $E[37;40m%prompt.bak%

EXIT /B 0

color注意:唯一的缺点是如果不明确知道,此技术会与用户 cmd 颜色设置(命令或设置)发生冲突。

- 希望这会有所帮助,因为由于开头提到的原因,这是我唯一可以接受的解决方案。--

编辑:

根据评论,我附上了另一个受@Jeb 启发的片段。它:

  • 演示如何获取和使用“Esc”字符运行时(而不是将其输入到编辑器)(Jeb 的解决方案)
  • 使用“本机”ECHO命令
  • 所以不影响局部PROMPT
  • 证明着色ECHO输出不可避免地会影响PROMPT颜色,因此无论如何必须重置颜色
@ECHO OFF

    :: ! To observe color effects on prompt below in this script
    ::   run the script from a fresh cmd window with no custom
    ::   prompt settings

    :: Only not to pollute the environment with the %\e% variable (see below)
    :: Not needed because of the `PROMPT` variable
    SETLOCAL

        :: Parsing the `escape` character (ASCII 27) to a %\e% variable
        :: Use %\e% in place of `Esc` in the [http://ascii-table.com/ansi-escape-sequences.php]
        FOR /F "delims=#" %%E IN ('"prompt #$E# & FOR %%E IN (1) DO rem"') DO SET "\e=%%E"

        :: Demonstrate that prompt did not get corrupted by the previous FOR
        ECHO ON
        rem : After for
        @ECHO OFF

        :: Some fancy ASCII ESC staff
        ECHO [          ]
        FOR /L %%G IN (1,1,10) DO (
            TIMEOUT /T 1 > NUL
            ECHO %\e%[1A%\e%[%%GC%\e%[31;43m.
            ECHO %\e%[1A%\e%[11C%\e%[37;40m]
        )

        :: ECHO another decorated text
        :: - notice the `%\e%[30C` cursor positioning sequence
        ::   for the sake of the "After ECHO" test below
        ECHO %\e%[1A%\e%[13C%\e%[32;47mHELLO WORLD%\e%[30C

        :: Demonstrate that prompt did not get corrupted by ECHOing
        :: neither does the cursor positioning take effect.
        :: ! But the color settings do.
        ECHO ON
        rem : After ECHO
        @ECHO OFF

    ENDLOCAL

    :: Demonstrate that color settings do not reset
    :: even when out of the SETLOCAL scope
    ECHO ON
    rem : After ENDLOCAL
    @ECHO OFF

    :: Reset the `PROMPT` color
    :: - `PROMPT` itself is untouched so we did not need to backup it.
    :: - Still ECHOING in color apparently collide with user color cmd settings (if any).
    :: ! Resetting `PROMPT` color this way extends the `PROMPT`
    ::   by the initial `$E[37;40m` sequence every time the script runs.
    :: - Better solution then would be to end every (or last) `ECHO` command
    ::   with the `%\e%[37;40m` sequence and avoid setting `PROMPT` altogether.
    ::   which makes this technique preferable to the previous one (before EDIT)
    :: - I am keeping it this way only to be able to
    ::   demonstrate the `ECHO` color effects on the `PROMPT` above.
    PROMPT $E[37;40m%PROMPT%

    ECHO ON
    rem : After PROMPT color reset
    @ECHO OFF

EXIT /B 0
于 2020-01-23T08:42:40.583 回答
4

我正在添加一个答案来解决上面一些评论中提到的问题:内联 ansi 颜色代码在 FOR 循环内(实际上,在任何带括号的代码块内)可能会出现异常。 下面的 .bat 代码演示了 (1) 内联颜色代码的使用,(2) 在 FOR 循环或带括号的代码块中使用内联颜色代码时可能发生的颜色故障,以及 (3) 解决方案问题。 当 .bat 代码执行时,测试 2 和 3 显示颜色代码失败,测试 4 显示没有失败,因为它实现了解决方案。

[编辑 2020-04-07:我发现了另一种可能比调用子程序更有效的解决方案。将 FINDSTR 短语括在括号中,如下行所示:

   echo success | (findstr /R success)

结束编辑]

注意:在我的(有限的)经验中,颜色代码问题仅在输入通过管道传输到代码块内的 FINDSTR 后才会出现。这就是以下 .bat 重现问题的方式。 颜色代码问题可能比管道到 FINDSTR 后更普遍。如果有人可以解释问题的性质,并且有更好的解决方法,我将不胜感激。

@goto :main
:resetANSI
EXIT /B
rem  The resetANSI subroutine is used to fix the colorcode
rem  bug, even though it appears to do nothing.

:main
@echo off
setlocal EnableDelayedExpansion

rem  Define some useful colorcode vars:
for /F "delims=#" %%E in ('"prompt #$E# & for %%E in (1) do rem"') do set "ESCchar=%%E"
set "green=%ESCchar%[92m"
set "yellow=%ESCchar%[93m"
set "magenta=%ESCchar%[95m"
set "cyan=%ESCchar%[96m"
set "white=%ESCchar%[97m"
set "black=%ESCchar%[30m"

echo %white%Test 1 is NOT in a FOR loop nor within parentheses, and color works right.
   echo %yellow%[Test 1] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is magenta and FINDSTR found and displayed 'success'.%yellow%
   echo %green%This is green.
echo %cyan%Test 1 completed.

echo %white%Test 2 is within parentheses, and color stops working after the pipe to FINDSTR.
(  echo %yellow%[Test 2] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success'.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 2 completed.

echo %white%Test 3 is within a FOR loop, and color stops working after the pipe to FINDSTR.
for /L %%G in (3,1,3) do (
   echo %yellow%[Test %%G] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   echo %magenta%This is supposed to be magenta and FINDSTR found and displayed 'success'.
   echo %green%This is supposed to be green.
)
echo %cyan%Test 3 completed.

echo %white%Test 4 is in a FOR loop but color works right because subroutine :resetANSI is 
echo called after the pipe to FINDSTR, before the next color code is used.
for /L %%G in (4,1,4) do (
   echo %yellow%[Test %%G] %green%This is Green, %magenta%this is Magenta, and %yellow%this is Yellow.
   echo %Next, the string 'success' will be piped to FINDSTR...
   echo success | findstr /R success
   call :resetANSI
   echo %magenta%This is magenta and FINDSTR found and displayed 'success'.
   echo %green%This is green.
)
echo %cyan%Test 4 completed.%white%

EXIT /B
于 2020-03-26T11:12:12.920 回答
3

不需要调用标签的非 Windows 10 用户的选项,避免了这样做的延迟。

下面是 findstr colorprint 例程的宏版本

用法 - 其中 BF 被替换为背景/前景色的十六进制数字值:%Col%{BF}{"string to print"}

@Echo off & CD "%TEMP%"
 For /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")
 Set "Col=For %%l in (1 2)Do if %%l==2 (Set "_Str="&(For /F "tokens=1,2 Delims={}" %%G in ("!oline!")Do Set "C_Out=%%G" & Set "_Str=%%~H")&(For %%s in (!_Str!)Do Set ".Str=%%s")&( <nul set /p ".=%DEL%" > "!_Str!" )&( findstr /v /a:!C_Out! /R "^$" "!_Str!" nul )&( del " !_Str!" > nul 2>&1 ))Else Set Oline="
 Setlocal EnableDelayedExpansion
rem /* concatenation of multiple macro expansions requires the macro to be expanded within it's own code block. */
 (%Col%{02}{"green on black,"}) & (%Col%{10}{black on blue})
 Echo/& (%Col%{04}{red on black}) & (%Col%{34}{" red on blue"})
Goto :Eof

一个更健壮的宏版本充满了错误处理。

@Echo off & PUSHD "%TEMP%"
rem /* Macro Definitions */
(Set  \n=^^^
%= macro newline Do not modify =%
)
(Set LF=^


%= linefeed. Do not modify =%)
 If "!![" == "[" (
  Echo/%%COL%% macro must be defined prior to delayed expansion being enabled
  Goto :end
 )
 For /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (set "DEL=%%a")
rem /* %hCol% - Alternate color macro; escaped for use in COL macro. No error checking. Usage: (%hCol:?=HEXVALUE%Output String) */
 Set "hCol=For %%o in (1 2)Do if %%o==2 (^<nul set /p ".=%DEL%" ^> "!os!" ^& findstr /v /a:? /R "^$" "!os!" nul ^& del "!os!" ^> nul 2^>^&1 )Else Set os="
rem /* %TB%   - used with substitution within COL macro to format help output; not fit for general use, */
 Set "TB=^&^< nul Set /P "=.%DEL%!TAB!"^&"
rem /* %COL%  - main color output macro. Usage: (%COL%{[a-f0-9][a-f0-9]}{String to Print}) */
 Set COL=Set "_v=1"^&Set "Oline="^& For %%l in (1 2)Do if %%l==2 (%\n%
  If not "!Oline!" == "" (%\n%
   Set "_Str="%\n%
   For /F "tokens=1,2 Delims={}" %%G in ("!oline!")Do (%\n%
    Set "Hex=%%G"%\n%
    Set "_Str=%%~H"%\n%
   )%\n%
   Echo/!Hex!^|findstr /RX "[0-9a-fA-F][0-9a-fA-F]" ^> nul ^|^| (Echo/^&(%hCol:?=04%Invalid - )%TB%(%hCol:?=06%Bad Hex value.)%TB%(%hCol:?=01%%%COL%%{!Hex!}{!_Str!})%TB:TAB=LF%(%hCol:?=02%!Usage!)^&Set "_Str="^&Set "_v=0")%\n%
   If not "!_Str!" == "" (%\n%
    ^<nul set /p ".=%DEL%" ^> "!_Str!"%\n%
    findstr /v /a:!Hex! /R "^$" "!_Str!" nul %\n%
    del "!_Str!" ^> nul 2^>^&1%\n%
   )Else If not !_v! EQU 0 (%\n%
    Echo/^&(%hCol:?=04%Invalid -)%TB%(%hCol:?=06%Arg 2 absent.)%TB%(%hCol:?=01%%%COL%%!Oline!)%TB:TAB=LF%(%hCol:?=04%Input is required for output string.)%TB:TAB=LF%(%hCol:?=02%!Usage!)%\n%
   )%\n%
  )Else (Echo/^&(%hCol:?=04%Invalid -)%TB%(%hCol:?=06%No Args)%TB:TAB=!TAB!!TAB!%(%hCol:?=01%%%COL%%!Oline!)%TB:TAB=LF%(%hCol:?=02%!Usage!))%\n%
 )Else Set Oline=
 Set "usage=%%COL%%{[a-f0-9][a-f0-9]}{String to Print}"
 For /F eol^=^%LF%%LF%^ delims^= %%A in ('forfiles /p "%~dp0." /m "%~nx0" /c "cmd /c echo(0x09"') do Set "TAB=%%A"
rem /* removes escaping from macros to enable use outside of COL macro */
 Set "hCol=%hCol:^=%"
 Set "TB=%TB:^=%"
 Setlocal EnableDelayedExpansion
 rem /* usage examples */
 (%COL%{02}{"green on black,"}) & (%COL%{10}{"black on blue"})
 Echo/
 (%COL%{04}{"red on black"}) & (%COL%{34}{" red on blue"})&(%COL%{40}{"black on red"})
 Echo/& %COL%{03}{Demonstration of error handling-}
rem /* error handling */
 Echo/%TB:TAB=!LF! % %hCol:?=20%Example 1 - No args
%COL%
 Echo/%TB:TAB=!LF! % %hCol:?=20%Example 2 - Missing 2nd Arg
%COL%{ff}
 Echo/%TB:TAB=!LF! % %hCol:?=20%Example 3 - Invalid hex value for 1st Arg
%COL%{HF}{string}
 Echo/%TB:TAB=!LF! % %hCol:?=0d%Done
:end
POPD
Goto :Eof

在此处输入图像描述

于 2020-11-24T19:07:13.897 回答
2

您可以使用 cecho .. 您也可以使用它直接嵌入到您的脚本中,这样您就不必携带 .com 或 .exe

http://www.codeproject.com/Articles/17033/Add-Colors-to-Batch-Files

于 2010-06-01T19:54:05.440 回答
2

用于处理 Windows 10 的光标颜色、位置和属性的高级宏。有关
使用信息,请参阅帮助和使用示例。

支持并展示以下示例:

  • 光标定位
    • 绝对
    • 相对于最后一个光标位置;左右 n 列;向上向下 n 行
    • 相对位置和绝对位置的组合。
  • 显示/隐藏光标
  • 光标图形属性 [ 颜色 ; 前景和背景]
    • 同线多色输出
    • 轻松链接多个 VT 图形序列。
  • 从给定位置清除一行上的所有文本。
  • 删除当前行光标右侧的多个字符。
  • 可以选择将扩展时的光标位置保存为独立的 Y 和 X 值。
    • /Save Cursor position storage components of the macro adpated from Jeb's answer here
  • 新:在屏幕缓冲区之间切换。

编辑:

我在最终使用示例下方包含了一个命令行,该命令行使用 VT 代码来实现与该示例相同的结果,以说明在同一光标输出中使用多个终端序列时可读性的差异。

更改缓冲区的注意事项:

光标位置与活动缓冲区相关联;切换到备用缓冲区时它不可用。
恢复到主缓冲区时:恢复
原来在主缓冲区中占用的光标位置,丢弃备用缓冲区的内容。

::: Cout cursor Macro. Author: T3RRY ::: Filename: Cout.bat
::: OS requirement: Windows 10
::: Purpose: Facilitate advanced console display output with the easy use of Virtual terminal codes
::: Uses a macro function to effect display without users needing to memorise or learn specific
::: virtual terminal sequences.
::: Enables output of text in 255 bit color at absolute or relative Y;X positions.
::: Allows cursor to be hidden or shown during and after text output. See help for more info.

@Echo off & Setlocal EnableExtensions
============================================== :# Usage
 If not "%~1" == "" Echo/%~1.|findstr /LIC:"/?" > nul && (
  If "%~2" == "" (Cls &  Mode 1000,50 & Color 30)
  If "%~2" == "Usage" ( Color 04 & ( Echo/n|choice /n /C:o 2> nul ) & timeout /T 5 > nul )
  If "%~2" == "DE" ( Color 04 & Echo/                      --- Delayed expansion detected^^^! Must not be enabled prior to calling %~n0 ---&( Echo/n|choice /n /C:o 2> nul ))
  If not Exist "%TEMP%\%~n0helpfile.~tmp" (For /F "Delims=" %%G in ('Type "%~f0"^| Findstr.exe /BLIC:":::" 2^> nul ')Do (
   For /F "Tokens=2* Delims=[]" %%v in ("%%G")Do Echo(^|%%v^|
  ))>"%TEMP%\%~n0helpfile.~tmp"
  Type "%TEMP%\%~n0helpfile.~tmp" | More
  timeout /T 60 > nul
  Color 07
  If "%~2" == "DE" (Exit)Else Exit /B 1
 )
 If "!![" == "[" Call "%~f0" "/?" "DE"
:::[=====================================================================================================================]
:::[ cout /?                                                                                                             ]
:::[ %COUT% Cursor output macro.                                                                                         ]
:::[ * Valid Args for COUT: {/Y:Argvalue} {/X:Argvalue} {/S:Argvalue} {/C:Argvalue}                                      ]
:::[       - Args Must be encased in curly braces. Arg order does not matter ; Each Arg is optional.                     ]
:::[ * Valid Switches for COUT: /Save /Alt /Main                                                                         ]
:::[ /Save - Stores the Y and X position at the start of the current expansion to .lY and .lX variables                  ]
:::[ /Alt  - Switch console to alternate screen Buffer. Persists until /Main switch is used.                             ]
:::[ /Main - Restore console to main screen Buffer. Console default is the main buffer.                                  ]
:::[                                                                                                                     ]
:::[   USAGE:                                                                                                            ]
:::[ * ArgValue Options ; '#' is an integer:                                                                             ]
:::[   {/Y:up|down|#} {/Y:up#|down#|#} {/Y:#up|#down|#} {/X:left|right|#} {/X:left#|right#|#} {/X:#left|#right|#}        ]
:::[  * note: {/Y:option} {/X:option} - 1 option only per Arg.                                                           ]
:::[        - directions: 'up' 'down' 'left' 'right' are relative to the cursors last position.                          ]
:::[         - /Y and /X options - #direction or direction#:                                                             ]
:::[           Positions the cursor a number of cells from the current position in the given direction.                  ]
:::[           Example; To move the cursor 5 rows up in the same column, without displaying any new text:                ]
:::[            %COUT%{/Y:5up}                                                                                           ]
:::[        - '#' (Absolute position) is the column number {/X:#} or row number {/Y:#} the cursor                        ]
:::[         * Integers for absolute positions contained in variables must be Expanded: {/Y:%varname%}                   ]
:::[           is to be positioned at, allowing cursor position to be set on single or multiple axis.                    ]
:::[         * Absolute Y and X positions capped at line and column maximum of the console display.                      ]
:::[         * Exceeding the maximum Y positions the cursor at the start of the last line in the console display.        ]
:::[         * Exceeding the maximum X positions the cursor at the start of the next line                                ]
:::[                                                                                                                     ]
:::[   {/S:Output String} {/S:(-)Output String} {/S:Output String(+)} {/S:Output String(K)} {/S:Output String(.#.)}      ]
:::[  * note: (-) Hide or (+) Show the Cursor during output of the string.                                               ]
:::[          (K) Clears the row of text from the position (K) occurs.                                                   ]
:::[          Example; Delete 5 characters from the current row to the right of the curser:                              ]
:::[           %COUT%{/S:(.5.)}                                                                                          ]
:::[   {/C:VTcode} {/C:VTcode-VTcode} {/C:VTcode-VTcode-VTcode}                                                          ]
:::[  * note: Chain multiple graphics rendition codes using '-'                                                          ]
:::[  See:      https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#text-formatting      ]
:::[  See also: https://www.rapidtables.com/web/color/RGB_Color.html                                                     ]
:::[=====================================================================================================================]

============================================== :# PreScript variable definitions

rem /* generate Vitual Terminal Escape Control .Character */
 For /F %%a in ( 'Echo prompt $E ^| cmd' )Do Set "\E=%%a"
rem /* https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences */
(Set \n=^^^

%= Newline variable for macro definitions. DO NOT MODIFY this line or above 2 lines. =%)

================== :# Screen Dimensions [Customise columns,lines using the mode command.]
 Mode 160,38 & Cls
rem /* Get screen dimensions [lines] [columns]. Must be done before delayed expansion is enabled. */
 For /F "tokens=1,2 Delims=:" %%G in ('Mode')Do For %%b in (%%H)Do For %%a in (%%G)Do Set "%%a=%%b"

rem /* NON ENGLISH VERSION USERS: You will need to manually set Columns and lines for their desired console size */
 If not defined columns (Set "columns=100"& Set "lines=30")

rem /* Cursor position codes - https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#simple-cursor-positioning */
 Set "left=D"&Set "right=C"&Set "up=A"&set "down=B"
 For /L %%n in (1 1 %lines%)Do (Set "%%ndown=[%%nB"&Set "down%%n=[%%nB"& set "%%nup=[%%nA"&Set "up%%n=[%%nA")
 For /L %%n in (1 1 %columns%)Do (Set "%%nleft=[%%nD"&Set "left%%n=[%%nD"&set "%%nright=[%%nC"&set "right%%n=[%%nC")

%= Catch Args        =%Set COUT=For %%n in (1 2)Do If %%n==2 ( %\n%
%= Test No Args       =%If "!Args!" == "" (CLS^&Echo/Usage Error. Args Required. ^& Call "%~f0" "/?" "Usage" ^|^| Exit /B 1) %\n%
%= Test Braces Used   =%If "!Args:}=!" == "!Args!" (CLS^&Echo/Usage Error. Args must be enclosed in curly braces ^& Call "%~f0" "/?" "Usage" ^|^| Exit /B 1) %\n%
%= Reset macro        =%Set ".Y=" ^& Set ".X=" ^& Set ".Str=" ^& Set ".C=" %\n%
%=  internal vars     =%Set "Arg1=" ^& Set "Arg2=" ^& Set "Arg3=" ^& Set "Arg4=" %\n%
%= Split Args.        =%For /F "Tokens=1,2,3,4 Delims={}" %%1 in ("!Args!")Do ( %\n%
%= Substring           =%Set "Arg1=%%~1" %\n%
%=  modification       =%Set "Arg2=%%~2" %\n%
%=  identifies Args    =%Set "Arg3=%%~3" %\n%
%=  during handling.   =%Set "Arg4=%%~4" %\n%
%=                    =%) %\n%
%= Check /Save switch =%If not "!Args:/Save=!" == "!Args!" (%\n%
%= Reset Cursor Save   =%Set ".Cpos=" ^&Set ".Char="%\n%
%= 10 char max; Repeat =%For /L %%l in (2 1 12)Do (%\n%
%= until R returned     =%If not "!.Char!" == "R" (%\n%
%= from esc[6n          =%^<nul set /p "=%\E%[6n" %\n%
%= Redirects to          =%FOR /L %%z in (1 1 %%l) DO pause ^< CON ^> NUL%\n%
%= prevent blocking      =%Set ".Char=;"%\n%
%= script execution      =%for /F "tokens=1 skip=1 delims=*" %%C in ('"REPLACE /W ? . < con"') DO (Set ".Char=%%C")%\n%
%= Append string w.out R =%If "!.Cpos!" == "" (Set ".Cpos=!.Char!")Else (set ".Cpos=!.Cpos!!.Char:R=!") %\n%
%=                      =%)%\n%
%=                     =%)%\n%
%= Split Captured Pos  =%For /F "tokens=1,2 Delims=;" %%X in ("!.Cpos!")Do Set ".lY=%%X" ^& Set ".LX=%%Y" %\n%
%= End of Pos /Save   =%)%\n%
%= Begin Arg          =%For %%i in (1 2 3 4)Do For %%S in (Y X C S)Do If not "!Arg%%i!" == "" ( %\n%
%= Processing. 4 Args   =%If not "!Arg%%i:/%%S:=!" == "!Arg%%i!" ( %\n%
%= Flagged with Y X C S  =%Set "Arg%%i=!Arg%%i:/%%S:=!" %\n%
%= Strip /Flag In Arg#   =%For %%v in ("!Arg%%i!")Do ( %\n%
%= /Y Lines Arg handling  =%If "%%S" == "Y" ( %\n%
%= Test if arg is variable =%If Not "!%%~v!" == "" ( %\n%
%= assign down / up value   =%Set ".Y=%\E%!%%~v!" %\n%
%= -OR-                    =%)Else ( %\n%
%= assign using operation   =%Set /A ".Y=!Arg%%i!" %\n%
%= to allow use of offsets; =%If !.Y! GEQ !Lines! (Set /A ".Y=Lines-1") %\n%
%= constrained to console   =%Set ".Y=%\E%[!.Y!d" %\n%
%= maximum lines.         =%)) %\n%
%= /X Cols Arg handling   =%If "%%S" == "X" ( %\n%
%= processing follows same =%If Not "!%%~v!" == "" ( %\n%
%= logic as /Y;            =%Set ".X=%\E%!%%~v!" %\n%
%= except if Columns     =%)Else ( %\n%
%= exceed console max     =%Set /A ".X=!Arg%%i!" %\n%
%= columns line wrapping   =%If !.X! GEQ !Columns! (Set ".X=1"^& Set ".Y=%\E%!Down!") %\n%
%= is effected.            =%Set ".X=%\E%[!.X!G" %\n%
%=                       =%)) %\n%
%= /C Color Arg Handling. %If "%%S" == "C" ( %\n%
%= Substituition          =%Set ".C=%\E%[!Arg%%i!" %\n%
%= replaces '-' with VT   =%Set ".C=!.C:-=m%\E%[!" %\n%
%= chain - m\E[           =%Set ".C=!.C!m" %\n%
%=                       =%) %\n%
%= /S String Arg Handle  =%If "%%S" == "S" ( %\n%
%=  Substitute Sub-Args   =%Set ".Str=!Arg%%i!" %\n%
%=  (-) hide cursor        =%Set ".Str=!.Str:(-)=%\E%[?25l!" %\n%
%=  (+) show cursor        =%Set ".Str=!.Str:(+)=%\E%[?25h!" %\n%
%=  (K) clear line         =%Set ".Str=!.Str:(K)=%\E%[K!" %\n%
%=  (.#.) delete # of      =%Set ".Str=!.Str:(.=%\E%[!" %\n%
%=  characters             =%Set ".Str=!.Str:.)=P!" %\n%
%=                       =%) %\n%
%= End Arg Handling   =%))) %\n%
%= /Main /Alt Switch  =%If not "!Args:/Main=!" == "!Args!" ( %\n%
%= handling for       =%^< nul Set /P "=%\E%[?1049l!.Y!!.X!!.C!!.Str!%\E%[0m" %\n%
%= switching console  =%)Else If not "!Args:/Alt=!" == "!Args!" ( %\n%
%= buffers. No Switch =%^< nul Set /P "=%\E%[?1049h!.Y!!.X!!.C!!.Str!%\E%[0m" %\n%
%= outputs to current =%)Else ( ^< nul Set /P "=!.Y!!.X!!.C!!.Str!%\E%[0m" ) %\n%
%= buffer.           =%)Else Set Args=
rem /* Simple subsecond delay macro. Uses call to a non existentent label # number of times to delay script execution. */
 For /F "tokens=1,2 delims==" %%G in ('wmic cpu get maxclockspeed /format:value')Do Set /A "%%G=%%H/20" 2> nul
 If not defined Maxclockspeed Set "Maxclockspeed=200"
 Set "Hash=#"& Set "delay=(If "!Hash!" == "#" (Set /A "Delay.len=Maxclockspeed")Else Set "Delay.len=#")& For /L %%i in (1 1 !Delay.Len!)Do call :[_false-label_] 2> Nul"

============================================== :# Script Body [Demo]
rem /* Enable Delayed Expansion after macro definiton in order to expand macro. */
 Setlocal EnableDelayedExpansion & CD "%TEMP%"
rem /* Usage examples */
 %COUT%{/X:10}{/Y:5}{/C:34}{"/S:(-)hello there^^^!"}
 %Delay%
rem /* Example use of mixed foreground / background color and other graphics rendition properties */
 %COUT%{"/C:31-1-4-48;2;0;80;130"}{/S:Bye for now.}{/Y:down}
 %Delay%
 %COUT%{/Y:up}{/C:35}{/S:again}{/X:16}
 %Delay%
 %COUT%{"/S:(K)^_^"}{/X:right}{/C:32}{/Y:down} /Save
 %Delay%
rem /* Switch to Alternate screen buffer: /Alt */
 %COUT%{"/S:(-)(K)o_o"}{/X:.lX+1}{/Y:6}{/C:33}{/Y:down} /Alt
 %Delay%
 %COUT%{"/S:Don't worry, they'll be back"}{/Y:down}{/X:15left}{/C:7-31}
rem /* Cursor position is tied to the active console buffer. The contents of the Alternate buffer are discarded when reverting to the Main buffer. */
 %Delay%
rem /* Return to Main screen buffer: /Main */
 %COUT%{/X:3left}{/Y:5up}{"/S:That's all folks."} /Save /Main
rem /* Cursor position is tied to the active console buffer. */
 %Delay%
rem /* restore cursor position /Save .lX value with +7 offset ; Overwrite all and delete 6 following characters:(.6.) ; restore cursor: (+) */
     %COUT%{/X:10left}{/S:How(.6.)(+)}{/C:32}
rem /* The same as the above line using VT codes manually. */
 ::: <nul Set /P "=%\E%[10D%\E%[32mHow%\E%[6P%\E%[?25l"
 %Delay%
 %COUT%{/Y:100}
 Endlocal
 Goto :eof

可以在此处找到上述宏的替代版本,该版本使用更简单且具有更好可读性的 arg 处理结构。

于 2021-01-22T13:43:10.240 回答
2

Windows XP以来,通过使用 PowerShell 作为通过命名管道链接到控制台输出的子进程,使用cmd 批处理有效地快速替代颜色。它也可以使用 FindStr 完成,但 PowerShell 提供了更多选项并且看起来更快。

将 PowerShell 保留为子进程并使用管道进行通信的主要兴趣在于,显示启动 PowerShell 或 FindStr 以显示每一行要快得多。

其他优点:

  • 不需要临时文件
  • 通过管道回显允许显示完整的 ASCII 表,而不会打扰转义。
  • 与 fd 重定向一起工作正常。仅以 stderr 为示例着色,或重定向到文件/其他进程。

这是执行此操作的示例代码:

::
:: Launch a PowerShell child process in the background linked to the console and 
:: earing through named pipe PowerShellCon_%PID%
::
:: Parameters :
::   [ PID ] : Console Process ID used as an identifier for the named pipe, launcher PID by default.
::   [ timeout ] : Subprocess max life in seconds, 300 by default. If -1, the subprocess
::                  will not terminate while the process %PID% is still alive.
:: Return :
::   0 if the child PowerShell has been successfully launched and the named pipe is available.
::   1 if it fails.
::   2 if we can't get a PID.
::   3 if PowerShell is not present or doesn't work.
::
:LaunchPowerShellSubProcess
  SET LOCALV_PID=
  SET LOCALV_TIMEOUT=300
  IF NOT "%~1" == "" SET LOCALV_PID=%~1
  IF NOT "%~2" == "" SET LOCALV_TIMEOUT=%~2
  powershell -command "$_" 2>&1 >NUL
  IF NOT "!ERRORLEVEL!" == "0" EXIT /B 3
  IF "!LOCALV_PID!" == "" (
    FOR /F %%P IN ('powershell -command "$parentId=(Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId; write-host (Get-WmiObject Win32_Process -Filter ProcessId=$parentId).ParentProcessId;"') DO (
      SET LOCALV_PID=%%P
    )
  )
  IF "!LOCALV_PID!" == "" EXIT /B 2
  START /B powershell -command "$cmdPID=$PID; Start-Job -ArgumentList $cmdPID -ScriptBlock { $ProcessActive = $true; $timeout=!LOCALV_TIMEOUT!; while((!LOCALV_TIMEOUT! -eq -1 -or $timeout -gt 0) -and $ProcessActive) { Start-Sleep -s 1; $timeout-=1; $ProcessActive = Get-Process -id !LOCALV_PID! -ErrorAction SilentlyContinue; } if ($timeout -eq 0 -or ^! $ProcessActive) { Stop-Process -Id $args; } } | Out-Null ; $npipeServer = new-object System.IO.Pipes.NamedPipeServerStream('PowerShellCon_!LOCALV_PID!', [System.IO.Pipes.PipeDirection]::In); Try { $npipeServer.WaitForConnection(); $pipeReader = new-object System.IO.StreamReader($npipeServer); while(($msg = $pipeReader.ReadLine()) -notmatch 'QUIT') { $disp='write-host '+$msg+';'; invoke-expression($disp); $npipeServer.Disconnect(); $npipeServer.WaitForConnection(); }; } Finally { $npipeServer.Dispose(); }" 2>NUL
  SET /A LOCALV_TRY=20 >NUL
  :LaunchPowerShellSubProcess_WaitForPipe
  powershell -nop -c "& {sleep -m 50}"
  SET /A LOCALV_TRY=!LOCALV_TRY! - 1 >NUL
  IF NOT "!LOCALV_TRY!" == "0" cmd /C "ECHO -NoNewLine|MORE 1>\\.\pipe\PowerShellCon_!LOCALV_PID!" 2>NUL || GOTO:LaunchPowerShellSubProcess_WaitForPipe
  IF "!LOCALV_TRY!" == "0" EXIT /B 1
  EXIT /B 0

此“代码”是在延迟扩展ON的情况下编写的,但可以在没有它的情况下重写以工作。有很多安全点需要考虑,不要直接在野外使用。

如何使用它 :

@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
IF ERRORLEVEL 1 (
  ECHO Extension inapplicable
  EXIT /B 1
)
::
SETLOCAL ENABLEDELAYEDEXPANSION
IF ERRORLEVEL 1 (
  ECHO Expansion inapplicable
  EXIT /B 1
)
CALL:LaunchPowerShellSubProcess
IF NOT ERRORLEVEL 0 EXIT /B 1
CALL:Color Cyan "I write this in Cyan"
CALL:Blue "I write this in Blue"
CALL:Green "And this in green"
CALL:Red -nonewline "And mix Red"
CALL:Yellow "with Yellow"
CALL:Green "And not need to trouble with ()<>&|;,%""^ and so on..."
EXIT /B 0
:Color
ECHO -foregroundcolor %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Blue
ECHO -foregroundcolor Blue %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Green
ECHO -foregroundcolor Green %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Red
ECHO -foregroundcolor Red %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
:Yellow
ECHO -foregroundcolor Yellow %*>\\.\pipe\PowerShellCon_!LOCALV_PID!
ECHO[|SET /P=>NUL
GOTO:EOF
::
:: Launch a PowerShell child process in the background linked to the console and 
:: earing through named pipe PowerShellCon_%PID%
::
:: Parameters :
::   [ PID ] : Console Process ID used as an identifier for the named pipe, launcher PID by default.
::   [ timeout ] : Subprocess max life in seconds, 300 by default. If -1, the subprocess
::                  will not terminate while the process %PID% is still alive.
:: Return :
::   0 if the child PowerShell has been successfully launched and the named pipe is available.
::   1 if it fails.
::   2 if we can't get a PID.
::   3 if PowerShell is not present or doesn't work.
::
:LaunchPowerShellSubProcess
  SET LOCALV_PID=
  SET LOCALV_TIMEOUT=300
  IF NOT "%~1" == "" SET LOCALV_PID=%~1
  IF NOT "%~2" == "" SET LOCALV_TIMEOUT=%~2
  powershell -command "$_" 2>&1 >NUL
  IF NOT "!ERRORLEVEL!" == "0" EXIT /B 3
  IF "!LOCALV_PID!" == "" (
    FOR /F %%P IN ('powershell -command "$parentId=(Get-WmiObject Win32_Process -Filter ProcessId=$PID).ParentProcessId; write-host (Get-WmiObject Win32_Process -Filter ProcessId=$parentId).ParentProcessId;"') DO (
      SET LOCALV_PID=%%P
    )
  )
  IF "!LOCALV_PID!" == "" EXIT /B 2
  START /B powershell -command "$cmdPID=$PID; Start-Job -ArgumentList $cmdPID -ScriptBlock { $ProcessActive = $true; $timeout=!LOCALV_TIMEOUT!; while((!LOCALV_TIMEOUT! -eq -1 -or $timeout -gt 0) -and $ProcessActive) { Start-Sleep -s 1; $timeout-=1; $ProcessActive = Get-Process -id !LOCALV_PID! -ErrorAction SilentlyContinue; } if ($timeout -eq 0 -or ^! $ProcessActive) { Stop-Process -Id $args; } } | Out-Null ; $npipeServer = new-object System.IO.Pipes.NamedPipeServerStream('PowerShellCon_!LOCALV_PID!', [System.IO.Pipes.PipeDirection]::In); Try { $npipeServer.WaitForConnection(); $pipeReader = new-object System.IO.StreamReader($npipeServer); while(($msg = $pipeReader.ReadLine()) -notmatch 'QUIT') { $disp='write-host '+$msg+';'; invoke-expression($disp); $npipeServer.Disconnect(); $npipeServer.WaitForConnection(); }; } Finally { $npipeServer.Dispose(); }" 2>NUL
  SET /A LOCALV_TRY=20 >NUL
  :LaunchPowerShellSubProcess_WaitForPipe
  powershell -nop -c "& {sleep -m 50}"
  SET /A LOCALV_TRY=!LOCALV_TRY! - 1 >NUL
  IF NOT "!LOCALV_TRY!" == "0" cmd /C "ECHO -NoNewLine|MORE 1>\\.\pipe\PowerShellCon_!LOCALV_PID!" 2>NUL || GOTO:LaunchPowerShellSubProcess_WaitForPipe
  IF "!LOCALV_TRY!" == "0" EXIT /B 1
  EXIT /B 0

链接到我关于同一主题的原始答案。

于 2021-03-12T18:07:42.447 回答
1

我刚刚从 Win 7 Home 转换为 Win 10 Pro,并想替换我从其他批次调用的批次以以颜色回显信息。回顾上面讨论的内容,我使用以下内容将直接替换我之前的批次。注意在消息中添加“~”以便可以使用带有空格的消息。我没有记住代码,而是使用字母来表示我需要的颜色。

如果 %2 包含空格,则需要“...” %1 黑色上的强烈颜色:R=红色 G=绿色 Y=黄色 W=白色

ECHO OFF
IF "%1"=="R" ECHO ^[91m%~2[0m
IF "%1"=="G" ECHO ^[92m%~2[0m
IF "%1"=="Y" ECHO ^[93m%~2[0m
IF "%1"=="W" ECHO ^[97m%~2[0m
于 2020-04-28T14:51:14.430 回答
1

这只是帮助,作为光学示例,在制作或修改彩色命令提示符回声时。

下面的代码由两部分组成。如果您也方便的话,这个 .cmd 文件中还有一个 .txt 格式,位于“双”行 (====) 下方。

::adonios77
::This is a .cmd file
@ECHO OFF
TITLE Colored Command Prompt echoes HELP
mode con: cols=55 lines=47
CLS
COLOR 0f 
echo [93m
ECHO This is just help, as optical example,
ECHO when make or modify colorful command prompt echoes.
ECHO.
ECHO More info in Source:
ECHO [4m[94mhttps://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line[0m

ECHO.
ECHO [0mESC[0m "Text" Default colours Text[0m
ECHO [7mESC[7m "Text" Inversed Back-Fore colors[0m 
ECHO [101mESC[101m "Text" in Red Background[0m
ECHO [91mESC[91m "Text" in Red Foreground)[0m

echo.
echo To make an ESC special character, (ASCII Escape code)
echo open or edit a .txt or .bat or .cmd file,
echo (hold)L-Alt and (type)027 in NumPad)
echo Or, in Command Prompt, (can't copy/paste special char.)
echo just press Ctrl+[ 
echo  (it should look like: "echo ^[[33m'Text'^[[0m")
echo. 
echo STYLES
echo [0mESC[0m Reset[0m
echo [1mESC[1m Bold [90m*This is not work for me[0m
echo [4mESC[4m Underline[0m
echo [7mESC[7m[0m Inverse
echo. 
echo COLORS#  Foreground-Background (color /? HEX) && echo.
echo           [90mDark[0m     /    [100mLight[0m
echo        Fore-Back   /  Fore-Back
echo Black  *   [100m[30m30[0m-[4m[40m40  [0m   (0) / (8) [90m90[0m-[100m100 [0m
echo Red        [31m31[0m-[41m41  [0m   (4) / (C) [91m91[0m-[101m101 [0m
echo Green      [32m32[0m-[42m42  [0m   (2) / (A) [92m92[0m-[102m102 [0m
echo Yellow         [33m33[0m-[90m[43m43  [0m   (6) / (E) [93m93[0m-[90m[103m103 [0m
echo Blue       [34m34[0m-[44m44  [0m   (1) / (9) [94m94[0m-[104m104 [0m
echo Magenta    [35m35[0m-[45m45  [0m   (5) / (D) [95m95[0m-[105m105 [0m
echo Cyan       [36m36[0m-[46m46  [0m   (3) / (B) [96m96[0m-[106m106 [0m
echo White  *   [37m37[0m-[47m47  [0m   (7) / (F) [97m97[0m-[7;97m107 [0m
echo. 
echo Note: use ESC[0m at the end of (every) line.
echo. 
echo COMBINATIONS
echo [7;91mESC[7;91m inverse red foreground color ESC[0m[0m
echo. 

ECHO. && PAUSE
exit

============================================================
:: This is a .txt file.
 This is just help, as optical example,
 when make or modify colorful command prompt echoes.

 More info in Source:
https://stackoverflow.com/questions/2048509/how-to-echo-with-different-colors-in-the-windows-command-line

To make an ESC special character, (),
open or edit a .txt or .bat or .cmd file,
(hold)L-Alt and (type)027 in NumPad)

STYLES
[0m Reset
[1m Bold
[4m Underline
[7m Inverse

COLORS#  (Foreground-Background)
            Dark        /     Light
        Fore-Back       /   Fore-Back
Black       30-40   (0) / (8)   90-100
Red         31-41   (4) / (C)   91-101
Green       32-42   (2) / (A)   92-102
Yellow      33-43   (6) / (E)   93-103
Blue        34-44   (1) / (9)   94-104
Magenta     35-45   (5) / (D)   95-105
Cyan        36-46   (3) / (B)   96-106
White       37-47   (7) / (F)   97-107

COMBINATIONS
ESC[7;31m inverse red foreground color 0m

Note: use ESC[0m at the end of (every) line.

examples:
@ECHO OFF
ECHO          Default Text
ECHO [7m"Text" Inversed Back-Fore colors (7m)[0m 
ECHO [101m"Text" in Red Background (101m)[0m
ECHO [91m"Text" in Red Foreground (91m)[0m

============================================================

另外,我发现通过这种方式可以临时或永久地改变命令提示符的外观。以下 TEXT 代码是以下示例:

SET_PROMPT_Colored.PNG

This is a .txt file.

 Antony's examples:

prompt $Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$S $T$_ $P\$_$G 
 gives something like that:

====================  19:53:02,73
 C:\Windows\system32\
> 

For All Users & Permanent: 
(if there is space between characters, must double quoted [""])
SETX PROMPT /M $Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$S$S$T$_$_$S$P\$_$G$S
 gives something like that:

====================   9:01:23,17

 C:\Windows\system32\
> 

NOTE: Variables created or modified by SETX
         will be available at the next logon session.

现在让我们给上面的例子涂上颜色。上图中的结果。

彩色提示示例:

仅针对当前用户:

prompt $E[91m$E[40m$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$S $T$E[93m$_ $P\$_$G$E[0m

或者

对于所有用户并且永久:

SETX PROMPT /M $E[91m$E[40m$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$Q$S$S$T$E[93m$_$_$S$P\$_$G$S$E[0m
于 2020-09-22T12:24:52.227 回答
1

对我来说,我找到了一些解决方案:这是一个可行的解决方案 在此处输入图像描述

     @echo off
    title a game for youtube 
explorer "https://thepythoncoding.blogspot.com/2020/11/how-to-echo-with-different-colors-in.html"
    SETLOCAL EnableDelayedExpansion
    for /F "tokens=1,2 delims=#" %%a in ('"prompt #$H#$E# & echo on & for %%b in (1) do rem"') do (
      set "DEL=%%a"
    )
    echo say the name of the colors, don't read
    
    call :ColorText 0a "blue"
    call :ColorText 0C "green"
    call :ColorText 0b "red"
    echo(
    call :ColorText 19 "yellow" 
    call :ColorText 2F "black"
    call :ColorText 4e "white"
    
    goto :Beginoffile
    
    :ColorText
    echo off
    <nul set /p ".=%DEL%" > "%~2"
    findstr /v /a:%1 /R "^$" "%~2" nul
    del "%~2" > nul 2>&1
    goto :eof
    
    :Beginoffile
于 2020-11-04T20:17:58.333 回答
0

您需要回显一个 ANSI 转义码序列来更改文本颜色:http ://en.wikipedia.org/wiki/ANSI_escape_code

这些转义码的另一个很好的来源是http://ascii-table.com/ansi-escape-sequences.php

于 2010-01-12T11:30:45.560 回答
0

将以下行放入ColourText.bas桌面上调用的文件中。

Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports Microsoft.Win32

Public Module MyApplication  
Public Declare Function GetStdHandle Lib "kernel32" Alias "GetStdHandle" (ByVal nStdHandle As Long) As Long
Public Declare Function SetConsoleTextAttribute Lib "kernel32" Alias "SetConsoleTextAttribute" (ByVal hConsoleOutput As Long, ByVal wAttributes As Long) As Long
Public Const STD_ERROR_HANDLE = -12&
Public Const STD_INPUT_HANDLE = -10&
Public Const STD_OUTPUT_HANDLE = -11&

Sub Main()
    Dim hOut as Long
    Dim Ret as Long
    Dim Colour As Long
    Dim Colour1 As Long
    Dim Text As String
    hOut  = GetStdHandle(STD_OUTPUT_HANDLE)
    Colour = CLng("&h" & Split(Command(), " ")(0))
    Colour1 = Clng("&h" & Split(Command(), " ")(1))
    Text = Mid(Command(), 7)
    Ret = SetConsoleTextAttribute(hOut,  Colour)
    Console.Out.WriteLine(text)
    Ret = SetConsoleTextAttribute(hOut, Colour1)
End Sub
End Module

保存它并在命令提示符下键入以下内容。

"C:\Windows\Microsoft.NET\Framework\v4.0.30319\vbc.exe" /target:exe /out:"%userprofile%\desktop\ColourText.exe" "%userprofile%\desktop\ColourText.bas" /verbose

一个名为 ColourText.exe 的文件将出现在您的桌​​面上。将其移至 Windows 文件夹

要使用,您必须使用两个字符代码来设置颜色,例如01not 1

ColourText ColourOfText ColourOfTextWhenFinished Text

EG 通过不传递任何文本来设置蓝底白字,然后在白底白字上设置红色,最后以蓝底灰结束。

ColourText F1 F1
ColourText F2 71 This is green on white

或者

ColourText F1 F1
cls
ColourText F4 F4
Echo Hello
Echo Hello today
ColourText F1 F1

CLS命令也变得有趣。Color不带参数的命令将所有颜色重置为启动颜色。

要获得颜色代码,请将以下数字加在一起。在程序员模式下使用计算器。这些是十六进制数字。它们可以加在一起,例如 Red + Blue + FG Intensity = 13 = D。由于未使用 10+,因此背景将为黑色。颜色代码必须是两个字符,例如08不是8

FOREGROUND_RED = &H4     '  text color contains red.
FOREGROUND_INTENSITY = &H8     '  text color is intensified.
FOREGROUND_GREEN = &H2     '  text color contains green.
FOREGROUND_BLUE = &H1     '  text color contains blue.
BACKGROUND_BLUE = &H10    '  background color contains blue.
BACKGROUND_GREEN = &H20    '  background color contains green.
BACKGROUND_INTENSITY = &H80    '  background color is intensified.
BACKGROUND_RED = &H40    '  background color contains red.
于 2017-01-01T21:55:05.600 回答
0

要使其在 Windows 10 上运行,您可以启用此标志:ENABLE_VIRTUAL_TERMINAL_PROCESSING.

使用此注册表项,您可以默认设置此项

[HKCU\Console] VirtualTerminalLevel dword 0x1

于 2017-07-12T10:16:58.570 回答
0

另一种方法是使用NodeJS

这是一个例子:

const os = require('os');
const colors = require('colors');

console.log("Operative System:".green,os.type(),os.release());
console.log("Uptime:".blue,os.uptime());

这是结果:

在此处输入图像描述

于 2019-02-10T21:51:58.003 回答
0

在 powershell 中为日志语句设置颜色并不是什么大问题。 你可以使用-ForegroundColor参数。

写确认信息。

Write-Host "Process executed Successfully...." -ForegroundColor Magenta

写一个错误信息。

Write-Host "Sorry an unexpected error occurred.." -ForegroundColor Red

写一个进度消息

Write-Host "Working under pocess..." -ForegroundColor Green
于 2020-04-15T05:48:54.470 回答
0
call :color_echo "blue" "blue txt"
call :color_echo "red" "red txt"
echo "white txt"


REM : https://www.robvanderwoude.com/ansi.php
:color_echo
    @echo off

    set "color=%~1"
    set "txt=%~2"

    set ESC=
    set black=%ESC%[30m
    set red=%ESC%[31m
    set green=%ESC%[32m
    set yellow=%ESC%[33m
    set blue=%ESC%[34m
    set magenta=%ESC%[35m
    set cyan=%ESC%[36m
    set white=%ESC%[37m

    if "%~1" == "black"   set "color=!black!"
    if "%~1" == "red"     set "color=!red!"
    if "%~1" == "green"   set "color=!green!"
    if "%~1" == "yellow"  set "color=!yellow!"
    if "%~1" == "blue"    set "color=!blue!"
    if "%~1" == "magenta" set "color=!magenta!"
    if "%~1" == "cyan"    set "color=!cyan!"
    if "%~1" == "white"   set "color=!white!"

    echo | set /p="!color!!txt!"
    echo.

    REM : return to standard white color
    echo | set /p="!white!"

    REM : exiting the function only
    EXIT /B 0
于 2020-04-25T08:37:31.093 回答
0

更改前景色和背景色以及无需换行书写的解决方案。
它不会创建任何临时文件。
不需要特殊的编辑器,因此可以使用记事本进行编辑。:color子例程 的第一个参数是颜色代码,其余(可选)参数是要显示的文本。如果最后一个参数是$则在末尾写入一个新行。 颜色代码与颜色命令相同。 : echo子例程可用于显示没有换行的文本(与常规回显不同)。

Windows 10 上的输出



@echo off
call :color 4
call :echo Red foreground
call :color 7 " and "
call :color 4f
echo Red background

call :color 
echo Back to normal

call :color 70 "Black "
call :color 1 "Blue "
call :color 2 "Green "
call :color 3 "Aqua "
call :color 4 "Red "
call :color 5 "Purple "
call :color 6 "Yellow "
call :color 7 "White "
call :color 8 "Gray "
call :color 9 "LightBlue" $
call :color a "LightGreen "
call :color b "LightAqua "
call :color c "LightRed "
call :color d "LightPurple "
call :color e "LightYellow "
call :color f "BrightWhite " $

call :color 1f Blue back
call :color 2f Green back
call :color 3f Aqua back
call :color 4f Red back
call :color 5f Purple back
call :color 6f Yellow back
call :color 7f White back
call :color 8f Gray back
call :color 9f "LightBlue back" $
call :color a0 LightGreen back
call :color b0 LightAqua back
call :color c0 LightRed back
call :color d0 LightPurple back
call :color e0 LightYellow back
call :color f0 LightWhite back $

call :color
echo %ESC%[4mUnderline%ESC%[0m.
pause 


goto :eof

:: Displays a text without new line at the end (unlike echo)
:echo
@<nul set /p ="%*"
@goto :eof

:: Change color to the first parameter (same codes as for the color command) 
:: And display the other parameters (write $ at the end for new line)
:color
@echo off
IF [%ESC%] == [] for /F %%a in ('echo prompt $E ^| cmd') do set "ESC=%%a"
SET color=0%1
IF [%color%] == [0] SET color=07
SET fore=%color:~-1%
SET back=%color:~-2,1% 
SET color=%ESC%[
if %fore% LEQ 7 (
  if %fore% == 0 SET color=%ESC%[30
  if %fore% == 1 SET color=%ESC%[34
  if %fore% == 2 SET color=%ESC%[32
  if %fore% == 3 SET color=%ESC%[36
  if %fore% == 4 SET color=%ESC%[31
  if %fore% == 5 SET color=%ESC%[35
  if %fore% == 6 SET color=%ESC%[33
  if %fore% == 7 SET color=%ESC%[37
) ELSE (
  if %fore% == 8 SET color=%ESC%[90
  if %fore% == 9  SET color=%ESC%[94
  if /i %fore% == a SET color=%ESC%[92
  if /i %fore% == b SET color=%ESC%[96
  if /i %fore% == c SET color=%ESC%[91
  if /i %fore% == d SET color=%ESC%[95
  if /i %fore% == e SET color=%ESC%[93
  if /i %fore% == f SET color=%ESC%[97
)
if %back% == 0 (SET color=%color%;40) ELSE (
  if %back% == 1 SET color=%color%;44
  if %back% == 2 SET color=%color%;42
  if %back% == 3 SET color=%color%;46
  if %back% == 4 SET color=%color%;41
  if %back% == 5 SET color=%color%;45
  if %back% == 6 SET color=%color%;43
  if %back% == 7 SET color=%color%;47
  if %back% == 8 SET color=%color%;100
  if %back% == 9  SET color=%color%;104
  if /i %back% == a SET color=%color%;102
  if /i %back% == b SET color=%color%;106
  if /i %back% == c SET color=%color%;101
  if /i %back% == d SET color=%color%;105
  if /i %back% == e SET color=%color%;103
  if /i %back% == f SET color=%color%;107
)
SET color=%color%m
:repeatcolor
if [%2] NEQ [$] SET color=%color%%~2
shift
if [%2] NEQ [] if [%2] NEQ [$] SET color=%color% & goto :repeatcolor
if [%2] EQU [$] (echo %color%) else (<nul set /p ="%color%")
goto :eof
于 2021-03-04T00:44:13.573 回答
0

最简单的方法是像这样对 powershell 进行系统调用:

s=os.system('powershell Write-Host "I am so bored with this. Work already" -ForegroundColor Blue')

除此以外 :

←[94mPff

在此处输入图像描述

于 2021-03-20T15:18:30.000 回答
-1

我们曾经使用ANSI 终端代码来做到这一点。不确定它们是否仍然有效,但您可以尝试一下。

于 2010-01-12T11:32:02.297 回答
-1

正如Glenn Slayden这个答案中所说,您可以在注册表中添加适当的值,以使 cmd “更加丰富多彩”。

幸运的是,全局默认值可以从选择加入更改为选择退出。HKEY_CURRENT_USER\Console\VirtualTerminalLevel 的注册表项设置处理 ANSI 转义序列的全局默认行为。创建一个 DWORD 键(如有必要)并将其值设置为 1 以全局启用(或 0 以禁用`)默认情况下的 ANSI 处理。

于 2019-03-19T13:27:11.563 回答
-4

您可以使用 color 命令更改整个控制台的颜色

Color 0F

是黑白的

Color 0A 

是黑色和绿色

于 2013-01-21T21:13:44.097 回答