【问题标题】:How to clear selected lines in Batch instead of the whole screen?如何批量清除选定的行而不是整个屏幕?
【发布时间】:2017-10-22 21:40:31
【问题描述】:

当我们使用pause 时,它会显示“按任意键继续...”。按下任意键后,后面的文字会保留下来,剩下的文字会出现在它的下方。如果我在pause 之后使用cls,整个屏幕都会被清除。

有什么方法可以只删除“按任意键继续...”按任意键后?另外,如何只清除选定的行而不是清除整个屏幕?

【问题讨论】:

  • 为什么不继续暂停后再次打印所有文本?
  • 我从没想过!但是有没有办法只清除选定的行而不是清除整个屏幕?

标签: batch-file cmd windows-console


【解决方案1】:

这个问题有多种解决方案,但批处理不提供一个简单

批处理的主要问题是,您无法使用普通命令将光标向上移动。

1) 您可以使用cls 清除屏幕并重新绘制所有必要的数据。

2) 您可以使用外部程序来移动光标(这些程序可以动态创建),例如Move Cursor to 0,0

3)你可以滥用timeout命令回到第二行 Move cursor to screen home with TIMEOUT command!,这是Aacini发现的一个很酷的技巧

4) 在 Windows 10 中,您可以使用 Ansi-Escape 序列来移动光标并获得许多其他效果,但它仅适用于 Win10

【讨论】:

  • 第一个选项在 imo 中效果很好。谢谢你:)
【解决方案2】:

cmd 中无法删除某些行。但是,我可以提供一种解决方法:

@echo off
rem // Enable delayed expansion which is necessary to output carriage-return characters later:
setlocal EnableDelayedExpansion
rem // Retrieve a carriage-return character:
for /F %%C in ('copy /Z "%~f0" nul') do set "CR=%%C"
rem // Retrieve a back-space character:
for /F %%C in ('echo prompt $H ^| cmd') do set "BS=%%C"
rem // Prepare message text and a string of spaces:
set "STRING=Press any key to continue . . . "
set "SPACES=                                "

rem // Use `set /P` to print message text without trailing line-break (carriage-return + line-feed):
set /P ="%STRING%" < nul
rem // Do `pause` but suppress its message text:
pause > nul
rem /* Use `set /P` to first print an invisible back-space character; this avoids a white-space
rem    character to appear first to `set /P` as it would not output such leading characters;
rem    then print a single carriage-return character to move the cursor to the beginning of the
rem    current line; then a string of spaces onto the previous message text to overwrite and so to
rem    clear it; append a single carriage-return character, so any other text is printed onto it;
rem    since there is no trailing line-break, any further text is printed at the same line: */
set /P ="%BS%!CR!%SPACES%!CR!" < nul
endlocal

【讨论】:

  • 需要说明的是,这段代码可以修改当前行。这可用于进度指示器
  • @jeb,我不会称之为“修改”而是“覆盖”;我现在在评论中提到了它。无论如何,我必须修复我的方法,因为需要延迟扩展才能返回 CR,并解决 set /P 不返回前导空格的事实......
【解决方案3】:

你也可以使用一个奇怪的技巧,结合一个 TAB 字符和几个 BS 字符来将光标向上移动任意行数:

@echo off
setlocal EnableDelayedExpansion

rem Get a BS and TAB control characters
for /F %%a in ('echo prompt $H ^| cmd') do set "BS=%%a"
set "TAB=   "  &  REM Be sure that TAB variable contains an Ascii 9 character

rem Leave some empty lines and do a PAUSE
echo Three empty lines below + pause
echo/
echo/
echo/
pause

rem Get width of screen buffer, set number of lines to go above
for /F "tokens=2" %%a in ('mode con ^| findstr "Col"') do set /A buffWid=%%a, linesAbove=3

rem Assemble the "go above" control string with the proper number of BSs
set "BSs="
set /A "cntBS = 2 + (buffWid + 7) / 8 * linesAbove"
for /L %%i in (1,1,%cntBS%) do set "BSs=!BSs!!BS!"

rem Move cursor up the desired number of lines
echo %TAB%!BSs!

echo Hello,
echo World
echo This line overwrites the one with PAUSE output

重要提示:您必须确保 set "TAB= " 行有效地包含 TAB (Ascii 9) 字符,而不仅仅是空格。

暂停前的输出:

Three empty lines below + pause



Presione una tecla para continuar . . .

...在暂停之后:

Three empty lines below + pause

Hello,
World
This line overwrites the one with PAUSE output

在 Windows 8.1 上测试

此方法由 DosTips 用户 neorobin 发现,并在 this topic 上进行了完整描述。

【讨论】:

  • 直到我注意到我的编程编辑器设置为将制表符转换为空格之前,我无法让它工作。我正在运行记事本以随时放置 TAB ,直到我找到 for /F "tokens=2 delims=1234567890" %%# in ('shutdown /?^|findstr /bc:"E"') do set "TAB=%%#" ... 所以不再需要 notepadding ;-) 。这是由用户找到的aGerman DosTips thread :new functions: :chr, :asc, :asciiMap
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多