批处理更改颜色的代码:它是如何工作的?

5
我发现了这段代码可以改变批处理文件中文本输出的颜色。请问有人可以解释一下它是如何工作的吗?
特别是,DEL变量的用途让我感到困惑,如果没有前面的那些行,着色根本不起作用,但当我回显它时,DEL变量似乎是空的。
@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

请解释一下for循环和ColorText方法。

1个回答

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

在这个代码块之后,DEL 变量中包含一个 <backspace><space><backspace> 字符串,该字符串是由 for 循环中的 prompt $H 创建的。
这样可以有效运行,因为 for 循环的命令块是:
prompt #$H#$E#
echo on 
for %%b in (1) do rem

这会首先将提示设置为#<BACKSPACE><SPACE><BACKSPACE>#<ESCAPE>#(这里的ESC无意义,我只是从我的字符串库中复制了它)。 但通常提示不会可见,所以我启用ECHO ON,然后您需要一些东西使提示出现,这将使用for %%b in (1) do rem来完成。
稍后,DEL字符将用作文件内容。
:ColorText
<nul set /p ".=%DEL%" > "%~2"
findstr /v /a:%1 /R "^$" "%~2" nul
del "%~2" > nul 2>&1

该函数的第一行创建一个文件,其内容为DEL变量。
文件名命名为您想要着色的字符串。
这对于findstr命令非常重要。 findstr /v /a:%1 /R "^$" "%~2" nul将通过/R "^$"查找任何行。
由于列出了两个文件(nul是第二个文件名),因此每个文件名都将被输出并由/a:%1的值着色。 由于文件NUL没有内容,因此根本不会输出它。
第一个文件名也将输出冒号,后跟文件内容。
例如,假设文件内容为ABC,文件名为Hello findstr的输出结果将为:
Hello:ABC

但是,如果我将<backspace><space><backspace>放入文件内容中,冒号将被删除。

del "%~2" > nul 2>&1最终会删除临时文件。


你能否请解释一下程序的流程?例如,退格键是如何生成的,提示部分是如何工作的,为什么要使用%%B(1)等等。此外,ColorText方法是如何工作的? - Subham Tripathi
提示符$H代表退格键,$E代表转义代码。但是,您说您会获得<BACKSPACE><SPACE><BACKSPACE><ESCAPE>,如何实现的?另外,为什么要使用#?为什么在findstr /v /a:%1 /R "^$" "%~2" nul命令中要使用nul? - Subham Tripathi
如所述,您需要两个文件名,否则findstr将不会显示文件名,因此我使用始终存在的空文件NUL作为第二个文件。prompt $H给出了<backspace><space><backspace>,文档是错误的。 是自由选择的分隔符之一。 - jeb
<nul 用于 set /p 的输入,否则它将等待用户输入。set ".=%DEL%" 只是输出 %DEL% 而没有换行符。 - jeb
最后一个问题 - 你提到我们需要两个文件名才能使用findstr,否则它不会提供输出。但我仍然困惑为什么它需要文件名? - Subham Tripathi
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接