5

I found this piece of code which helps to change colors of text output in a batch file. Can someone please explain how it works?

Especially what is the use of DEL variable puzzles me, and without those first lines, the coloring doesn't work at all, but the DEL variable appears to be empty when I echo it.

@echo on
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 0b "red"
echo(
call :ColorText 19 "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

Also please shed some light on for loop and the ColorText method

Abel
  • 56,041
  • 24
  • 146
  • 247
Subham Tripathi
  • 2,683
  • 6
  • 41
  • 70

1 Answers1

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

After this block, the DEL variable contains a <backspace><space><backspace> string, created in the FOR loop by the prompt $H.
This works, as the command block for the for-loop is

prompt #$H#$E#
echo on 
for %%b in (1) do rem

This sets the prompt first to #<BACKSPACE><SPACE><BACKSPACE>#<ESCAPE># (The escape is senseless here, I just copied it from my string library).
But normally the prompt wouldn't be visible, so I enable ECHO ON and then you need something that the prompt would appear and that will be done with the for %%b in (1) do rem.

The DEL character will be used later as file content.

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

The first line of this function creates a file with the content of the DEL variable.
The filename is named like the string you want to color.
This is important for the findstr command.

The findstr /v /a:%1 /R "^$" "%~2" nul will be find any line by /R "^$".
As two files are listed (nul is the second filename) each filename will be outputted and colored by the value of /a:%1. As the file NUL has no content it will not be outputted at all.
And the first filename will be outputted also with a colon followed by the file content.

Sample, assume the file content is ABC and the filename is Hello

The output of findstr would be

Hello:ABC

But as I place the <backspace><space><backspace> into the file content the colon will be deleted.

The del "%~2" > nul 2>&1 deletes the temporary file after all.

jeb
  • 78,592
  • 17
  • 171
  • 225
  • can you please explain with the flow of the program ? as in how are backspaces are generated and how the prompt part working , and why %%B (1) is used etc .. also how is ColorText method working ? – Subham Tripathi May 04 '15 at 08:37
  • why have used `nul` in `findstr /v /a:%1 /R "^$" "%~2" nul` ? also what is the need of `/R "^$"` , will it find all the files present in the current working directory ? – Subham Tripathi May 04 '15 at 09:03
  • also i still can't comprehend use of `prompt #$H#$E# & echo on & for %%b in (1) do rem` – Subham Tripathi May 04 '15 at 09:04
  • As explained, `/R "^$"` finds each line in a file (there is exactly one line). To understand the `prompt ...` just try it from an batch file – jeb May 04 '15 at 09:16
  • prompt `$H` gives `backspace` , `$E` gives escape code. but u said u will get .. how ? also why u have used `#` ? and why have used nul in findstr /v /a:%1 /R "^$" "%~2" nul ? – Subham Tripathi May 04 '15 at 09:22
  • As written, you need two filenames, else findstr will not shown the filename at all, therefore I use as second file the always existing empty file `NUL`. prompt $H gives `` the doku is wrong. The `#` is one chosen freely character as delimiter. – jeb May 04 '15 at 09:51
  • thnx ... what is the use of ` "%~2" and why u have set value of `DEL` to `.` ? – Subham Tripathi May 04 '15 at 10:01
  • one last question - You mentioned we need two file names for findstr else it won't provide output. but i am still confused on why it wants to file names ? – Subham Tripathi May 04 '15 at 11:12
  • With a single filename `findstr` works too, but it supresses the filename when it outputs matching lines – jeb May 04 '15 at 11:31