1

My batch code (Specifically designed to simply change the color) fails because the replace code fails. The text it is supposed to replace comes out like it entered.

echo Colors:
echo Black, blue, green, red, purple, yellow, white, gray, light blue, light   green, light aqua, light red, light purple, light yellow, and bright white.
set /p COLOR=What color for the background? 
set DASH=%COLOR: =-%
set COLORSETBACK=%DASH:black=0%
set COLORSETBACK=%DASH:blue=1%
set COLORSETBACK=%DASH:green=2%
set COLORSETBACK=%DASH:aqua=3%
set COLORSETBACK=%DASH:red=4%
set COLORSETBACK=%DASH:purple=5%
set COLORSETBACK=%DASH:yellow=6%
set COLORSETBACK=%DASH:white=7%
set COLORSETBACK=%DASH:gray=8%
set COLORSETBACK=%DASH:grey=8%
set COLORSETBACK=%DASH:light-blue=9%
set COLORSETBACK=%DASH:light-green=A%
set COLORSETBACK=%DASH:light-aqua=B%
set COLORSETBACK=%DASH:light-red=C%
set COLORSETBACK=%DASH:light-purple=D%
set COLORSETBACK=%DASH:light-yellow=E%
set COLORSETBACK=%DASH:bright-white=F%
cls
echo Colors:
echo Black, blue, green, red, purple, yellow, white, gray, light blue, light   green, light aqua, light red, light purple, light yellow, and bright white.
set /p COLOR=What color for the text? 
set DASH=%COLOR: =-%
set COLORSETTEXT=%DASH:black=0%
set COLORSETTEXT=%DASH:blue=1%
set COLORSETTEXT=%DASH:green=2%
set COLORSETTEXT=%DASH:aqua=3%
set COLORSETTEXT=%DASH:red=4%
set COLORSETTEXT=%DASH:purple=5%
set COLORSETTEXT=%DASH:yellow=6%
set COLORSETBACK=%DASH:white=7%
set COLORSETTEXT=%DASH:gray=8%
set COLORSETTEXT=%DASH:grey=8%
set COLORSETTEXT=%DASH:light-blue=9%
set COLORSETBACK=%DASH:light-green=A%
set COLORSETTEXT=%DASH:light-aqua=B%
set COLORSETTEXT=%DASH:light-red=C%
set COLORSETTEXT=%DASH:light-purple=D%
set COLORSETTEXT=%DASH:light-yellow=E%
set COLORSETTEXT=%DASH:bright-white=F%
color %COLORSETBACK%%COLORSETTEXT%

The set DASH=%COLOR: =-% is to change "light red" to light-red" and it works. However when I get to the set COLORSETTEXT=%DASH:black=0% the code fails to replace black with 0. I have tried different questions on different parts of the internet with no luck. If I were to type in red for the background and black for the text, the output would be "redblack" and I need it to be "40"

  • I see what I did wrong - if I used the same variable, it might work... –  May 18 '16 at 22:11

2 Answers2

6

Your code execute all lines each time that a color is read. For example, if the given color is black, the first line correctly change "black" by "0", but after it the rest of lines are executed, so the last line execute set COLORSETBACK=%DASH:bright-white=F% and the original value of DASH is not changed (because it does not contain "bright-white"), so black is finally assigned again. This means that your code only works when the color read is the last one: "bright-white".

Your code should have and if command for each value, so the rest of replacements be omitted when the right replacement is done. However, this produce very long and ugly code...

The correct way to "process a series of values in the same way" is via a for command that vary the value of a subscript in combination with the array concept:

@echo off
setlocal EnableDelayedExpansion

rem Define the "color" array used in the replacement:
set hex=0123456789ABCDEF
set i=0
for %%a in (Black, blue, green, aqua, red, purple, yellow, white, gray,
            light-blue, light-green, light-aqua, light-red, light-purple, light-yellow, bright-white) do (
   for %%i in (!i!) do set "color[%%a]=!hex:~%%i,1!"
   set /A i+=1
)

echo Colors:
echo Black, blue, green, red, purple, yellow, white, gray, light blue, light green, light aqua, light red, light purple, light yellow, and bright white.
set /p COLOR=What color for the background? 
set DASH=%COLOR: =-%
set COLORSETBACK=!color[%DASH%]!

cls
echo Colors:
echo Black, blue, green, red, purple, yellow, white, gray, light blue, light green, light aqua, light red, light purple, light yellow, and bright white.
set /p COLOR=What color for the text? 
set DASH=%COLOR: =-%
set COLORSETTEXT=!color[%DASH%]!

color %COLORSETBACK%%COLORSETTEXT%

You may read a further description of array management in Batch files at Arrays, linked lists and other data structures in cmd.exe (batch) script

PS - You have also a couple errors in these lines placed in the TEXT section:

set COLORSETBACK=%DASH:white=7%
set COLORSETBACK=%DASH:light-green=A%

EDIT: I added the "aqua" color that was missing in the original code. I also made good use of this edit in order to add a smaller solution:

@echo off
setlocal EnableDelayedExpansion

rem Define the "color" array used in the replacement:
set "colors=Black, blue, green, aqua, red, purple, yellow, white, gray, light-blue, light-green, light-aqua, light-red, light-purple, light-yellow, bright-white"
set "hex=0123456789ABCDEF"
set "i=0"
for %%a in (%colors%) do (
   for %%i in (!i!) do set "color[%%a]=!hex:~%%i,1!"
   set /A i+=1
)

for %%c in (background text) do (
   cls
   echo Colors:
   echo %colors:-= %
   set /p COLOR=What color for the %%c?
   set "%%c=!color[%COLOR: =-%]!"
)

color %background%%text%
Community
  • 1
  • 1
Aacini
  • 65,180
  • 12
  • 72
  • 108
  • This works... However lots of colors are mixed up. Yellow is purple, bright white is yellow, ect.. –  Mar 05 '16 at 14:57
  • Well, this is because you forgot to include "aqua" color between "green" and "red"! Just insert it in the `for` command... – Aacini Mar 05 '16 at 16:29
2

I modified your code - does it do what you need?

By uncommenting the two REM statements, they can show you how the text is modified.

@echo off
set "foreground="
set "background="

cls
echo Color choices:
echo Black, blue, green, red, purple, yellow, white, gray, light blue, light   green, light aqua, light red, light purple, light yellow, and bright white.
echo(
:loop
if not defined foreground set type=text
if not defined background set type=background
set "color="
set /p "COLOR=What color for the %type%? : "
set COLOR=%COLOR: =-%
rem echo %color%
set COLOR=%COLOR:light-blue=9%
set COLOR=%COLOR:light-green=A%
set COLOR=%COLOR:light-aqua=B%
set COLOR=%COLOR:light-red=C%
set COLOR=%COLOR:light-purple=D%
set COLOR=%COLOR:light-yellow=E%
set COLOR=%COLOR:bright-white=F%
set COLOR=%COLOR:black=0%
set COLOR=%COLOR:blue=1%
set COLOR=%COLOR:green=2%
set COLOR=%COLOR:aqua=3%
set COLOR=%COLOR:red=4%
set COLOR=%COLOR:purple=5%
set COLOR=%COLOR:yellow=6%
set COLOR=%COLOR:white=7%
set COLOR=%COLOR:gray=8%
set COLOR=%COLOR:grey=8%
rem echo %color%
if not defined background set background=%color%&goto :loop
if not defined foreground set foreground=%color%
echo(
echo color %background%%foreground%
pause
foxidrive
  • 40,353
  • 10
  • 53
  • 68
  • This code works fine. It seems like this is exactly what I had written in a different fashion, but it doesn't matter as long as it works. Thanks! –  Mar 05 '16 at 15:01