Windows批处理:没有换行的echo

时间:2011-08-18 09:46:34

标签: windows batch-file cmd newline

什么是Linux批处理命令echo -n的Windows批处理,它会在输出结尾处抑制换行符?

想法是在循环内写入同一行。

19 个答案:

答案 0 :(得分:204)

使用set/p参数,您可以在没有换行符的情况下进行回音:

C:\> echo Hello World
Hello World

C:\> echo|set /p="Hello World"
Hello World
C:\>

Source

答案 1 :(得分:87)

使用:echo | set /p=<NUL set /p=都可以抑制换行符。

但是,在检查ERRORLEVEL变得很重要时编写更多高级脚本会非常危险,因为设置set /p=而不指定变量名称会将ERRORLEVEL设置为1。

更好的方法是使用虚拟变量名称,如下所示:
echo | set /p dummyName=Hello World

这将产生你想要的东西而没有任何偷偷摸摸的东西在后台发生,因为我必须找到困难的方式,但这只适用于管道版本; <NUL set /p dummyName=Hello仍会将ERRORLEVEL提升为1。

答案 2 :(得分:26)

简单的SET / P方法具有Windows版本之间略有不同的限制。

  • 可能会删除引号

  • 可能会剥离前导空格

  • 引导=会导致语法错误。

有关详细信息,请参阅http://www.dostips.com/forum/viewtopic.php?f=3&t=4209

jeb发布了一个聪明的解决方案,解决了Output text without linefeed, even with leading space or =中的大多数问题我已经改进了方法,以便它可以安全地打印任何有效的批处理字符串而不需要新行,从XP开始的任何版本的Windows上。请注意,:writeInitialize方法包含的字符串文字可能无法很好地发布到网站。包括描述字符序列应该是什么的注释。

优化:write:writeVar方法,以便只使用我修改过的jeb的COPY方法编写包含麻烦的前导字符的字符串。使用更简单,更快速的SET / P方法编写非麻烦的字符串。

@echo off
setlocal disableDelayedExpansion
call :writeInitialize
call :write "=hello"
call :write " world!%$write.sub%OK!"
echo(
setlocal enableDelayedExpansion
set lf=^


set "str= hello!lf!world^!!!$write.sub!hello!lf!world"
echo(
echo str=!str!
echo(
call :write "str="
call :writeVar str
echo(
exit /b

:write  Str
::
:: Write the literal string Str to stdout without a terminating
:: carriage return or line feed. Enclosing quotes are stripped.
::
:: This routine works by calling :writeVar
::
setlocal disableDelayedExpansion
set "str=%~1"
call :writeVar str
exit /b


:writeVar  StrVar
::
:: Writes the value of variable StrVar to stdout without a terminating
:: carriage return or line feed.
::
:: The routine relies on variables defined by :writeInitialize. If the
:: variables are not yet defined, then it calls :writeInitialize to
:: temporarily define them. Performance can be improved by explicitly
:: calling :writeInitialize once before the first call to :writeVar
::
if not defined %~1 exit /b
setlocal enableDelayedExpansion
if not defined $write.sub call :writeInitialize
set $write.special=1
if "!%~1:~0,1!" equ "^!" set "$write.special="
for /f delims^=^ eol^= %%A in ("!%~1:~0,1!") do (
  if "%%A" neq "=" if "!$write.problemChars:%%A=!" equ "!$write.problemChars!" set "$write.special="
)
if not defined $write.special (
  <nul set /p "=!%~1!"
  exit /b
)
>"%$write.temp%_1.txt" (echo !str!!$write.sub!)
copy "%$write.temp%_1.txt" /a "%$write.temp%_2.txt" /b >nul
type "%$write.temp%_2.txt"
del "%$write.temp%_1.txt" "%$write.temp%_2.txt"
set "str2=!str:*%$write.sub%=%$write.sub%!"
if "!str2!" neq "!str!" <nul set /p "=!str2!"
exit /b


:writeInitialize
::
:: Defines 3 variables needed by the :write and :writeVar routines
::
::   $write.temp - specifies a base path for temporary files
::
::   $write.sub  - contains the SUB character, also known as <CTRL-Z> or 0x1A
::
::   $write.problemChars - list of characters that cause problems for SET /P
::      <carriageReturn> <formFeed> <space> <tab> <0xFF> <equal> <quote>
::      Note that <lineFeed> and <equal> also causes problems, but are handled elsewhere
::
set "$write.temp=%temp%\writeTemp%random%"
copy nul "%$write.temp%.txt" /a >nul
for /f "usebackq" %%A in ("%$write.temp%.txt") do set "$write.sub=%%A"
del "%$write.temp%.txt"
for /f %%A in ('copy /z "%~f0" nul') do for /f %%B in ('cls') do (
  set "$write.problemChars=%%A%%B    ""
  REM the characters after %%B above should be <space> <tab> <0xFF>
)
exit /b

答案 3 :(得分:9)

SET / P中剥离空白区域的解决方案:

诀窍是你可以在文本编辑器 EDIT 中为DOS召唤的退格字符。要在EDIT中创建它,请按 ctrlP + ctrlH 。 我会将其粘贴在此处,但此网页无法显示。它虽然可以在记事本上看到(它很糟糕,就像一个中间有白色圆圈的黑色小矩形)

所以你写这个:

<nul set /p=.9    Hello everyone

点可以是任何字符,它只是告诉SET / P文本在那里开始,在空格之前,而不是在&#34; Hello &# 34 ;. &#34; 9 &#34;是我无法在此显示的退格字符的表示。您必须将其替换为9,它将删除&#34; &#34;之后你会得到这个:

    Hello Everyone

而不是:

Hello Everyone

我希望它有所帮助

答案 4 :(得分:8)

作为@ xmechanix答案的附录,我注意到将内容写入文件:

echo | set /p dummyName=Hello World > somefile.txt

这会在打印字符串的末尾添加额外空格,这可能会带来不便,特别是因为我们试图避免在最后添加新行(另一个空白字符)字符串。

幸运的是,引用要打印的字符串,即使用:

echo | set /p dummyName="Hello World" > somefile.txt

将打印字符串,最后没有任何换行符或空格字符。

答案 5 :(得分:7)

您可以使用gnuwin32(coreutils包)中的“tr”删除换行符

@echo off
set L=First line
echo %L% | tr -d "\r\n"
echo Second line
pause

顺便说一句,如果你正在做大量的脚本编写,gnuwin32就是一个金矿。

答案 6 :(得分:5)

这是另一种方法,它使用Powershell Write-Host,它具有-NoNewLine参数,将其与start /b结合使用,它提供了批处理相同的功能。

NoNewLines.cmd

@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - ';Write-Host -NoNewLine 'Result 2 - ';Write-Host -NoNewLine 'Result 3 - '"
PAUSE

输出

Result 1 - Result 2 - Result 3 - Press any key to continue . . .

下面这个略有不同,并不像OP想要的那样工作,但很有趣,因为每个结果都会覆盖模拟计数器的前一个结果。

@ECHO OFF
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 1 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 2 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 3 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 4 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 5 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 6 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 7 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 8 - '"
start /b /wait powershell.exe -command "Write-Host -NoNewLine 'Result 9 - '"
PAUSE

答案 7 :(得分:3)

  

来自here

Inverse (X) =
 [[ 1.33333333 -3.          0.66666667]
 [ 0.83333333 -2.          0.16666667]
 [-0.66666667  1.         -0.33333333]]

Inv1 (X) =
 [[ 1.33333333 -3.          0.66666667]
 [ 0.83333333 -2.          0.16666667]
 [-0.66666667  1.         -0.33333333]]

Inverse X from numpy =
 [[ 1.33333333 -3.          0.66666667]
 [ 0.83333333 -2.          0.16666667]
 [-0.66666667  1.         -0.33333333]]

,也可以使用空格开头回显

"ERROR: Unable to autodetect JDBC driver for url: jdbc:hive2://HOSTNAME:10000/DATABASE;principal=hive/HOSTNAME@PRINCIPAL" 

答案 8 :(得分:2)

也许这就是你要找的东西,它是一个古老的学校剧本......:P

set nl=^& echo. 
echo %nl%The%nl%new%nl%line%nl%is%nl%not%nl%apparent%nl%throughout%nl%text%nl%
echo only in prompt.
pause

或者您尝试更换当前行而不是写入新行? 你可以通过删除&#34;%bs%&#34;来试验这个。在&#34;。&#34;之后签署并通过隔开其他&#34;%bs%&#34;在&#34;示例消息&#34;。

之后
for /f %%a in ('"prompt $H&for %%b in (1) do rem"') do set "bs=%%a"
<nul set /p=.%bs%         Example message         %bs%
pause

我发现这非常有趣,因为它将变量用于其他目的以外的目的。你可以看到&#34;%bs%&#34;代表退格。第二个&#34;%bs%&#34;使用退格键在&#34;示例消息后添加空格&#34;分离&#34; Pause命令的输出&#34;在&#34;示例消息&#34;之后没有实际添加可见字符。但是,这也可以使用常规百分号。

答案 9 :(得分:2)

DIY cw.exe(控制台写入)实用程序

如果找不到现成的现成产品,则可以进行DIY。借助此cw实用程序,您可以使用各种字符。至少,我想这样。请对其进行压力测试,让我知道。

工具

您只需要安装.NET,这在当今非常普遍。

材料

键入/粘贴了某些字符。

步骤

  1. 使用以下内容创建.bat文件。
/* >nul 2>&1

@echo off
setlocal

set exe=cw
for /f "tokens=* delims=" %%v in ('dir /b /s /a:-d  /o:-n "%SystemRoot%\Microsoft.NET\Framework\*csc.exe"') do set "csc=%%v"

"%csc%" -nologo -out:"%exe%.exe" "%~f0"

endlocal
exit /b %errorlevel%

*/

using System;

namespace cw {
    class Program {
        static void Main() {
            var exe = Environment.GetCommandLineArgs()[0];
            var rawCmd = Environment.CommandLine;
            var line = rawCmd.Remove(rawCmd.IndexOf(exe),exe.Length).TrimStart('"');
            line = line.Length < 2 ? "\r" : line.Substring(2) ;
            Console.Write(line);
        }
    }
}
  1. 运行它。

  2. 现在您有了一个不错的4KB实用程序,因此可以删除.bat

或者,您可以将此代码作为子例程插入任何批处理中,将生成的.exe发送到%temp%,在批处理中使用它,并在完成后将其删除。

使用方法

如果您想写一些没有换行的内容:
cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".

如果您想返回回车符(行首),只需运行
cw

因此,请从命令行尝试:

for /l %a in (1,1,1000) do @(cw ^|&cw&cw /&cw&cw -&cw&cw \&cw)

答案 10 :(得分:1)

示例1:这样可以生成退出代码= 0.这很好。 注意“。” ,直接在echo之后。

  

C:\ Users \ phife.dog \ gitrepos \ 1 \ repo_abc \ scripts#
  @echo。| set / p JUNK_VAR =这是一条显示的消息,如Linux echo -n将显示它...&amp; echo%ERRORLEVEL%

这是一条显示的消息,如Linux echo -n将显示它... 0

示例2:这适用于,但会产生退出代码= 1.这很糟糕。 回声后请注意缺少“。”。这似乎是不同的。

  

C:\ Users \ phife.dog \ gitrepos \ 1 \ repo_abc \ scripts#
  @echo | set / p JUNK_VAR =这是一条显示的消息,如Linux echo -n将显示它...&amp; echo%ERRORLEVEL%

这是一条显示的消息,如Linux echo -n将显示它... 1

答案 11 :(得分:1)

我用@arnep的想法制作了一个函数:

  

echo | set / p =“ Hello World”

在这里:

:SL (sameline)
echo|set /p=%1
exit /b

call :SL "Hello There"一起使用
我知道这没什么特别的,但是我花了很长时间才想到它,所以我想把它张贴在这里。

答案 12 :(得分:1)

受此问题答案的启发,我制作了一个简单的计数器批处理脚本,该脚本始终在同一行上打印进度值(0-100%)(覆盖了前一个)。也许这对于其他寻求类似解决方案的人也很有价值。

备注*是不可打印字符,应使用[Alt + Numpad 0 + Numpad 8]组合键输入,即backspace字符。

@ECHO OFF

FOR /L %%A in (0, 10, 100) DO (     
    ECHO|SET /P="****%%A%%"    
    CALL:Wait 1
)

GOTO:EOF

:Wait
SET /A "delay=%~1+1"
CALL PING 127.0.0.1 -n %delay% > NUL
GOTO:EOF

答案 13 :(得分:0)

这里的答案很晚,但是对于那些需要在一行中写特殊字符的人来说,dbenham的答案是大约80行太长且脚本可能会中断(可能是由于用户) -input)在简单使用set /p的限制下,将.bat或.cmd与已编译的C ++或C语言可执行文件配对,然后只需coutprintf角色。如果您显示某种进度条或某些使用字符的内容,这也可以让您轻松地多次写入一行,如OP显而易见的那样。

答案 14 :(得分:0)

我相信没有这样的选择。或者你可以尝试这个

set text=Hello
set text=%text% world
echo %text%

答案 15 :(得分:0)

您可以使用set / p命令禁止新行。 set / p命令无法识别空格,因为您可以使用点和退格符来识别它。您还可以将变量用作存储器并存储要在其中打印的内容,以便您可以打印变量而不是句子。例如:

@echo off
setlocal enabledelayedexpansion
for /f %%a in ('"prompt $H & for %%b in (1) do rem"') do (set "bs=%%a")
cls
set "var=Hello World! :)"
set "x=0"

:loop
set "display=!var:~%x%,1!"
<nul set /p "print=.%bs%%display%"
ping -n 1 localhost >nul
set /a "x=%x% + 1"
if "!var:~%x%,1!" == "" goto end
goto loop

:end
echo.
pause
exit

通过这种方式,您可以在没有换行的情况下打印任何内容。我已经让程序逐个打印字符,但你也可以通过改变循环来使用单词而不是字符。

在上面的示例中,我使用了“enabledelayedexpansion”,因此set / p命令无法识别“!”字符并打印一个点而不是那个。我希望你没有使用感叹号“!” ;)

答案 16 :(得分:0)

带有空格且没有换行符的回声

如先前Pedro所述,回声不带换行且具有前面的空格有效(提供的“ 9”是真实的[BackSpace])。

@ECHO ON

SET Letters=(A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z)
SET Numbers=(0,1,2,3,4,5,6,7,8,9)

FOR %%A IN %Letters% DO MOVE "%%~A*.*" "%%~A\"
FOR %%B IN %Numbers% DO MOVE "%%~B*.*" "#\"

我在使用新控制台在Windows 10中运行时遇到了一些问题,但采用以下方式进行管理。
在CMD中输入:

<nul set /p=.9    Hello everyone

通过按[Alt] + [8]来获得“◘”
(实际符号可能会因代码页而异)。

然后,使用Notepad.exe将结果从“ bs.txt”轻松复制到需要的地方。

echo .◘>bs.txt

答案 17 :(得分:0)

使用Bill Stewart的出色“ Shell脚本工具包”中的EchoX.EXE。
如何在Windows Cmd脚本中禁止换行:

@Echo Off
Rem Print three Echos in one line of output
EchoX -n "Part 1 - "
EchoX -n "Part 2 - "
EchoX    "Part 3"
Rem

给予:

Part 1 - Part 2 - Part 3
{empty line}
d:\Prompt>

此用法的帮助是:

Usage: echox [-n] message
  -n       Do not skip to the next line.
  message  The text to be displayed.

该实用程序小于48K,应该位于您的Path中。它可以做的更多事情:
-在不移动到下一行的情况下打印文本
-在一定宽度内以左,中或右对齐的文本
-使用制表符打印文本,换行和退回
-以前景色和背景色打印文本

该工具包还包含十二种很棒的脚本技巧。
The download page还托管其他三个有用的工具包。

答案 18 :(得分:0)

使用 jscript:

@if (@X)==(@Y) @end /*
    @cscript //E:JScript //nologo "%~nx0" %*
    @exit /b %errorlevel%
*/if(WScript.Arguments.Count()>0) WScript.StdOut.Write(WScript.Arguments.Item(0));

如果它被称为 write.bat 你可以像这样测试它:

call write.bat string & echo _Another_String_

如果您想使用 powershell 但使用 cmd 定义的变量,您可以使用:

set str=_My_StrinG_
powershell "Write-Host -NoNewline ""%str%""""  & echo #Another#STRING#