覆盖 Windows 批处理文件中的行?

覆盖 Windows 批处理文件中的行?

在我说任何话之前,我已经尝试过这个代码:

@echo off

setlocal enableextensions enabledelayedexpansion
for /f %%a in ('copy /Z "%~dpf0" nul') do set "ASCII_13=%%a"

set /p "=Example 1" <NUL

set /p "=!ASCII_13!Example 2" <NUL

我的消息来源:如何覆盖批处理文件命令输出中的同一行(来自其中的经过验证的答案)

但这对我来说不起作用。Example 1Example 2它只是像我尝试时 那样输出。

所以我只需要一种方法来覆盖批处理文件中的同一行(例如,它之前显示“示例 1”,但之后将显示“示例 2”)。

谢谢!

答案1

<nul set /p=text是一个技巧,用于回显一个字符串(文本提示),而末尾不加换行符,因此光标将停留在同一行,我们稍后可以返回到行首(发送回车符)来覆盖它。

您发现的指示答案的问题是 中的行为变化set /p。在 Windows XP 之前,该set /p命令能够在文本提示符的开头回显空格,但从 Vista 开始,白色字符从提示符的开头被删除。您不能在字符串的开头发送回车符。但您可以在其他地方使用它

@echo off
    setlocal enableextensions enabledelayedexpansion

    for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"

    <nul set /p"=This is the line 1 !CR!"
    <nul set /p"=This is the line 2 "

也就是说,不是将其发送CR到一行的开头,而是将其发送到上一行的结尾。

另一个选项是在 之前包含一个不同的字符作为文本提示的开头CR。包含可见字符会产生另一个问题,因为它应该在下一行被覆盖,因此不可见。退格键 (ascii 0x08) 是一个安全的(通常)选项

@echo off
    setlocal enableextensions enabledelayedexpansion

    for /f %%a in ('copy /Z "%~dpf0" nul') do set "CR=%%a"
    for /f %%a in ('"prompt $H&for %%b in (0) do rem"') do set "BS=%%a"

    <nul set /p"=This is the line 1"
    <nul set /p"=!BS!!CR!This is the line 2"

答案2

从 Windows 10 Treshold2 开始,控制台理解
Ansi 转义代码
这些代码需要转义字符十六进制 0x1b 或十进制 27,这
很难生成(取决于您的编辑器)

转到第一列和 n 行的代码是ESC[nF
删除到行尾的代码是ESC[0J

这两段代码合在一起(一行):

    esc [ 1  F  esc [ 0  J  
hex 1B 5B 31 46 1B 5B 30 4A  

此批处理使用 certutil 将十六进制字符串解码为 ascii

@echo off
echo 1B 5B>ESC.hex
Del ESC.bin >NUL 2>&1
certutil -decodehex ESC.hex ESC.bin >NUL 2>&1
Set /P ESC=<ESC.bin
set "Ansi=%ESC%1F%ESC%0J"

Echo line 1
Echo line 2
Echo line 3
Echo line 4

Timeout /t 3 >Nul

Echo %ESC%4F1st line
Timeout /t 1 >Nul
Echo 2nd line
Timeout /t 1 >Nul
Echo 3rd line
Timeout /t 1 >Nul
Echo 4th line

Echo New first Line extra long to see it's deleted, not overwritten
Timeout /t 3 >Nul
Echo %Ansi%Overwrite Line once
Timeout /t 2 >Nul
Echo %Ansi%Overwrite Line twice
Timeout /t 2 >Nul
Echo %Ansi%Overwrite Line thrice

相关内容