在同一行中回显

9

我看了一下你数据库之前的问题,没有尝试回答,但是我会尝试。

我想写以下代码:

echo Executing backup....
backup procedure
echo Ok

但是输出应该是:
Executing backup... Ok

"那真的可能吗?!"

1
你正在使用哪个操作系统? - Gary
是的,Windows Server 2003,我忘了... - user461487
5个回答

11

我猜你正在使用dos/nt-batch。

通过使用set /p命令,这是可能的,因为set /p不会输出回车和换行符。

set /p "=Executing backup...." <nul
echo OK

另外,可以使用CR字符删除该行。但需要注意,在set /p开头的空白字符会被忽略(在Vista中是这样,在XP中不是),因此!cr!必须放在后面或最后。 只有在delayedExpansion下才能显示CR,因为%cr%可以工作,但CR字符会在百分比展开阶段(或直接在此阶段后)被移除,而不是在延迟扩展阶段。

一个只使用一行显示计数器的示例

@echo off
setlocal EnableDelayedExpansion EnableExtensions


call :CreateCR
for /l %%n in (1,1,10000) do (
    set /P "=Count %%n!CR!" <nul
)
echo(
goto :eof

:CreateCR
rem setlocal EnableDelayedExpansion EnableExtensions
set "X=."
for /L %%c in (1,1,13) DO set X=!X:~0,4094!!X:~0,4094!

echo !X!  > %temp%\cr.tmp
echo\>> %temp%\cr.tmp
for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do (
   endlocal
   set cr=%%a
   goto :eof
)
goto :eof

编辑:解释变量 cr 的创建方式(通过诀窍完成)

将变量 X 设为单个点(字符本身并不重要),使用 for /L %%c in (1,1,13) DO set X=!X:~0,4094!!X:~0,4094! 使其重复8188次。

然后,将该变量、两个空格以及 CR 和 LF 四个字符一起写入文件中,使用命令 echo !X! > %temp%\cr.tmp (注意在 !X!> 之间有两个空格,并且 echo 命令会自动添加自然换行符)。

此时我们得到了8192个字符,但是数据缓冲区只能容纳8191个字符,因此最后一个字符(换行符)将被丢弃!

接下来,使用命令 echo\>> %temp%\cr.tmp 再向文件中追加一个 CR 和 LF(命令中的 \ 只为输出除回车和换行符外的内容,因为 echo 命令默认会输出“ECHO is ON/OFF”)。这很重要,因为单独的 CR 字符无法读取末尾行(稍后解释)。

因此,文件现在包含 <8188个点><空格><空格><CR><CR><LF> 这些字符。

接下来,for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do 命令读取第二个 token,分隔符为标准空格和制表符,因此第二个 token 只是单个的 CR,因为后面的 CR/LF 已经作为标准行结束而被删除了。

最后使用 endlocal 返回到没有临时变量 Xca 的环境中(由于括号内的 endlocal 允许在实际结束之前设置 cr,因此它也可以写成 for /f "tokens=2 usebackq" %%a in ("%temp%\cr.tmp") do endlocal&set cr=%%a&goto :eof)。

此外

这是我创建 CR 字符的第一种方法,但需要一些时间和一个临时文件。
后来我看到了更简单的从 copy /z 命令中获取 CR 的方法。

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

在结尾添加 <nul (例如 set /p "=执行备份中...." <nul)似乎能够起到同样的作用,如果我在这个位置看到它,也不会(至少)让我困惑,因此建议对此帖子进行编辑。 - user66001
@jeb - 有趣的反例。虽然我能理解大部分内容,但有几个问题不确定 - 1)一旦处理命令发布标签CreateCR,它如何返回到调用标签CreateCR的命令发布,2)变量cr中包含什么导致下一个set /p输出不会与前一个并排。我想我可以看到for循环设置X只是指数增加了%temp%\cr.tmp中的'.'数量,但然后不知道如何使用\并将其用作下一个for循环中的分隔符。也许其他人会欣赏全面的逐步说明? - user66001
似乎在使用setlocal EnableExtensions时,call和goto具有额外的功能(microsoft.com/resources/documentation/windows/xp/all/proddocs/… & microsoft.com/resources/documentation/windows/xp/all/proddocs/…)。 - user66001
http://www.dostips.com/ 对我理解 deb 的非常狡猾的代码很有帮助。 - user66001
@jeb - 另外,1)“rem setlocal EnableDelayedExpansion EnableExtensions”是否必要?2)当(我猜测)从0到4094的扩展表达式字符串操作重复了. 4094 x 2,但循环运行了13次时,字符串操作如何创建8188个点?3)在此中usebackq有什么作用?4)%temp%\cr.tmp不能只包含<8188 .'s><SPACE><CR><CR><LF>吗?因为将其替换为代码会将<CR><CR><LF>放入第二个标记。5)set cr=set /p或其他内容是否会删除最后的CR/LF作为标准行尾? - user66001
显示剩余4条评论

5

@Piotr Czapla - 我不认为每个集合后面的/(Windows示例)是必需的,或者至少似乎没有/也可以正常工作。但是,在尝试删除它们时,有人阻止了编辑,因此可能是错误的http://stackoverflow.com/questions/13665411/what-does-a-forward-slash-before-a-pipe-in-cmd-do-to-remove-the-line-ending-of-a#comment18755645_13665411。您能否建议/的需要? - user66001
管道会创建新的 cmd.exe 实例,这个信息在其他相关帖子中也有提到(请查看我的回复)。 - George Birbilis

1

这是一个有点hack的方法,但是在Windows上可以使用文章描述如何实现

从文章中,最终结果(根据您的设置进行编辑)如下:

SET /P var=Backing up
%Result%....<NUL

Backup_process %Result% >NUL 2>&1

IF ERRORLEVEL 1 
  ECHO FAIL 
ELSE
  ECHO OK

0

因为你晚了四年,并且和被采纳的答案完全一样。 - SomethingDark
你是认真的吗?我在这里发送的答案来自另一个线程。这里被接受的答案是一些非常长的文本。 - George Birbilis
在第一个代码块中,将“set /p”重定向到“nul”。所以,是的,这是相同的解决方案。 - SomethingDark
好的,当然。除此之外还有很多其他的文本 - 无论如何,我主要对复制粘贴文本时管道的行为信息感兴趣。 - George Birbilis

0

我曾经使用VBScript做过类似的事情。

将以下代码放入EchoNoNewline.vbs文件中:

If WScript.Arguments.Named.Exists("TEXT") Then
  WScript.StdOut.Write WScript.Arguments.Named.Item("TEXT")
End If

从您的批处理文件中,使用以下脚本:

CSCRIPT EchoNoNewLine.vbs //NOLOGO /TEXT:"Executing backup...."
backup procedure
CSCRIPT EchoNoNewLine.vbs //NOLOGO /TEXT:"Ok"

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