How to have multiple colors in a Windows batch file?

daniel11 picture daniel11 · Dec 2, 2010 · Viewed 122.4k times · Source

I was wondering if its possible to have different colored text on the same line in a Windows batch file, for example if it says

echo hi world

I want "hi" to be one color, and "world" to be another color. Maybe I could set the COLOR command as a variable:

set color1= color 2
set color9= color A

and then deploy them both on the same line along with

echo hi world

but I don't know how I would do that.

Answer

jeb picture jeb · Mar 17, 2011

You can do multicolor outputs without any external programs.

@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"
)
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 :eof

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

It uses the color feature of the findstr command.

Findstr can be configured to output line numbers or filenames in a defined color.
So I first create a file with the text as filename, and the content is a single <backspace> character (ASCII 8).
Then I search all non empty lines in the file and in nul, so the filename will be output in the correct color appended with a colon, but the colon is immediatly removed by the <backspace>.

EDIT: One year later ... all characters are valid

@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"
)

rem Prepare a file "X" with only one dot
<nul > X set /p ".=."

call :color 1a "a"
call :color 1b "b"
call :color 1c "^!<>&| %%%%"*?"
exit /b

:color
set "param=^%~2" !
set "param=!param:"=\"!"
findstr /p /A:%1 "." "!param!\..\X" nul
<nul set /p ".=%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%%DEL%"
exit /b

This uses the rule for valid path/filenames.
If a \..\ is in the path the prefixed elemet will be removed completly and it's not necessary that this element contains only valid filename characters.