How to echo with different colors in the Windows command line

前端 未结 23 1247
野性不改
野性不改 2020-11-22 08:55

I know that the color bf command sets the colors of the whole command line window but I wanted to to print one single line in a different color.

相关标签:
23条回答
  • 2020-11-22 09:24

    There is an accepted answer with more than 250 upvotes already. The reason I am still contributing is that the escape character required for echoing is not accepted by many editors (I am using, e.g., MS Code) and all other solutions require some third-party (non-Windows-default) pieces of software.

    The work-around with using only plain batch commands is using PROMPT instead of ECHO. The PROMPT command accepts the escape character in an any-editor-friendly way as a $Echaracter sequence. (Simply replace the Esc in the ASCII Escape codes) with $E.

    Here is a demo code:

    @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
    

    NOTE: The only drawback is that this technique collides with user cmd color settings (color command or settings) if not known explicitly.

    -- Hope this helps as thi is the only solution acceptable for me for the reasons mentioned at the beginning. --

    EDIT:

    Based on comments, I am enclosing another snippet inspired by @Jeb. It:

    • Shows how to obtain and use the "Esc" character runtime (rather than entering it to an editor) (Jeb's solution)
    • Uses "native" ECHO command(s)
    • So it does not affect local PROMPT value
    • Demonstrates that coloring the ECHO output inevitably affect PROMPT color so the color must be reset, anyway
    @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
    
    0 讨论(0)
  • 2020-11-22 09:26

    I was annoyed by the lack of proper coloring in cmd too, so I went ahead and created cmdcolor. It's just an stdout proxy, which looks for a limited set of ANSI/VT100 control sequences (in other words, like in bash), i.e. echo \033[31m RED \033[0m DEFAULT | cmdcolor.exe.

    Usage and downloads.

    0 讨论(0)
  • 2020-11-22 09:26

    We used to do this with ANSI terminal codes. Not sure if they still work, but you could try them.

    0 讨论(0)
  • 2020-11-22 09:26

    As Glenn Slayden said in this answer, you can add to the registry the proper value to make the cmd "more colorful".

    Fortunately, the global default can be changed from opt-in to opt-out. The registry key at HKEY_CURRENT_USER\Console\VirtualTerminalLevel sets the global default behavior for processing ANSI escape sequences. Create a DWORD key (if necessary) and set its value to 1 to globally enable (or 0 to disable`) ANSI processing by default.

    0 讨论(0)
  • 2020-11-22 09:27

    This isn't a great answer, but if you know the target workstation has Powershell you can do something like this (assuming BAT / CMD script):

    CALL:ECHORED "Print me in red!"
    
    :ECHORED
    %Windir%\System32\WindowsPowerShell\v1.0\Powershell.exe write-host -foregroundcolor Red %1
    goto:eof
    

    Edit: (now simpler!)

    It's an old answer but I figured I'd clarify & simplify a bit

    img

    PowerShell is now included in all versions of Windows since 7. Therefore the syntax for this answer can be shortened to a simpler form:

    • the path doesn't need to be specified since it should be in the environment variable already.
    • unambiguous commands can be abbreviated. For example you can:
      • use -fore instead of -foregroundcolor
      • use -back instead of -backgroundcolor
    • the command can also basically be used 'inline' in place of echo
      (rather than creating a separate batch file as above).

    Example:

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

    More Information:

    The complete list of colors and more information is available in the
    - PowerShell Documentation for Write-Host

    0 讨论(0)
  • 2020-11-22 09:32

    You'll need to echo an ANSI escape code sequence to alter the text colour: http://en.wikipedia.org/wiki/ANSI_escape_code

    Another very good source of these escape codes is http://ascii-table.com/ansi-escape-sequences.php

    0 讨论(0)
提交回复
热议问题