Windows 批处理:echo 没有换行

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7105433/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 08:41:49  来源:igfitidea点击:

Windows batch: echo without new line

windowsbatch-filecmdnewline

提问by gregseth

What is the Windows batch equivalent of the Linux shell command echo -nwhich suppresses the newline at the end of the output?

echo -n在输出末尾抑制换行符的 Linux shell 命令的 Windows 批处理等效项是什么?

The idea is to write on the same line inside a loop.

这个想法是在循环内的同一行上写。

回答by arnep

Using setand the /pparameter you can echo without newline:

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

C:\> echo Hello World
Hello World

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

Source

来源

回答by xmechanix

Using: echo | set /p=or <NUL set /p=will both work to suppress the newline.

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

However, this can be very dangerous when writing more advanced scripts when checking the ERRORLEVEL becomes important as setting set /p=without specifying a variable name will set the ERRORLEVEL to 1.

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

A better approach would be to just use a dummy variable name like so:
echo | set /p dummyName=Hello World

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

This will produce exactly what you want without any sneaky stuff going on in the background as I had to find out the hard way, but this only works with the piped version; <NUL set /p dummyName=Hellowill still raise the ERRORLEVEL to 1.

这将产生您想要的内容,而不会在后台发生任何偷偷摸摸的事情,因为我必须找出困难的方法,但这仅适用于管道版本;<NUL set /p dummyName=Hello仍会将 ERRORLEVEL 提高到 1。

回答by dbenham

The simple SET /P method has limitations that vary slightly between Windows versions.

简单的 SET /P 方法的局限性在 Windows 版本之间略有不同。

  • Leading quotes may be stripped

  • Leading white space may be stripped

  • Leading =causes a syntax error.

  • 前导引号可能会被删除

  • 前导空白可能会被剥离

  • 领先=会导致语法错误。

See http://www.dostips.com/forum/viewtopic.php?f=3&t=4209for more information.

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

jeb posted a clever solution that solves most of the problems at Output text without linefeed, even with leading space or =I've refined the method so that it can safely print absolutely any valid batch string without the new line, on any version of Windows from XP onward. Note that the :writeInitializemethod contains a string literal that may not post well to the site. A remark is included that describes what the character sequence should be.

jeb 发布了一个聪明的解决方案,它解决了在没有换行的情况下输出文本中的大多数问题,即使有前导空格或 =我已经改进了该方法,以便它可以在任何版本的 Windows 上安全地打印绝对没有新行的任何有效批处理字符串从 XP 开始。请注意,该:writeInitialize方法包含可能无法很好地发布到站点的字符串文字。包含的注释描述了字符序列应该是什么。

The :writeand :writeVarmethods are optimized such that only strings containing troublesome leading characters are written using my modified version of jeb's COPY method. Non-troublesome strings are written using the simpler and faster SET /P method.

:write:writeVar方法进行了优化,使得只有含麻烦的前导字符的字符串都使用我的杰布的复制方法的修改后的版本写的。不麻烦的字符串是使用更简单、更快的 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

回答by Joan Bruguera

As an addendum to @xmechanix's answer, I noticed through writing the contents to a file:

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

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

That this will add an extra space at the end of the printed string, which can be inconvenient, specially since we're trying to avoid adding a new line (another whitespace character) to the end of the string.

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

Fortunately, quoting the string to be printed, i.e. using:

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

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

Will print the string without any newline or space character at the end.

将打印末尾没有任何换行符或空格字符的字符串。

回答by Pedro

A solution for the stripped white space in SET /P:

SET /P 中去除空白的解决方案:

the trick is that backspace char which you can summon in the text editor EDITfor DOS. To create it in EDIT press ctrlP+ctrlH. I would paste it here but this webpage can't display it. It's visible on Notepad though (it's werid, like a small black rectangle with a white circle in the center)

诀窍是,退格字符,你可以在文本编辑器召唤编辑为DOS。要在 EDIT 中创建它,请按ctrlP+ctrlH。我想把它贴在这里,但这个网页不能显示它。虽然它在记事本上可见(它很奇怪,就像一个黑色的小矩形,中间有一个白色的圆圈)

So you write this:

所以你写这个:

<nul set /p=.9    Hello everyone

The dot can be any char, it's only there to tell SET /P that the text starts there, before the spaces, and not at the "Hello". The "9" is a representation of the backspace char that I can't display here. You have to put it instead of the 9, and it will delete the "." , after which you'll get this:

点可以是任何字符,它只是告诉 SET /P 文本从那里开始,在空格之前,而不是在“ Hello”处。“ 9”是我无法在此处显示的退格字符的表示。你必须把它而不是 9,它会删除“ .”,之后你会得到这个:

    Hello Everyone

instead of:

代替:

Hello Everyone

I hope it helps

我希望它有帮助

回答by BearCode

You can remove the newline using "tr" from gnuwin32 (coreutilspackage)

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

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

By the way, if you are doing lots of scripting, gnuwin32 is a goldmine.

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

回答by Knuckle-Dragger

Here is another method, it uses Powershell Write-Host which has a -NoNewLine parameter, combine that with start /band it offers the same functionality from batch.

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

NoNewLines.cmd

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

Output

输出

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

This one below is slightly different, doesn't work exactly like the OP wants, but is interesting because each result overwrites the previous result emulating a counter.

下面的这个略有不同,不像 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

回答by Afdsafnadsjbcewjhwnfy4ntc874fg

From here

这里

<nul set /p =Testing testing

and also to echo beginning with spaces use

并且还以空格开头的 echo 使用

echo.Message goes here

回答by cdlvcdlv

DIY cw.exe(console write) utility

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

If you don't find it out-of-the-box, off-the-shelf, you can DIY. With this cwutility you can use every kind of characters. At least, I'd like to think so. Please stress-test it and let me know.

如果您没有发现它是开箱即用的、现成的,您可以 DIY。使用此cw实用程序,您可以使用各种字符。至少,我愿意这么认为。请对其进行压力测试并让我知道。

Tools

工具

All you need is .NETinstalled, which is very common nowadays.

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

Materials

材料

Some characters typed/copy-pasted.

输入/复制粘贴的一些字符。

Steps

脚步

  1. Create .batfile with the following content.
  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. Run it.

  2. Now you have a nice 4KB utility so you can delete the .bat.

  1. 运行。

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

Alternatively, you can insert this code as a subroutine in any batch, send the resulting .exeto %temp%, use it in your batch and delete it when you're done.

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

How to use

如何使用

If you want write something without new line:
cw Whatever you want, even with "", but remember to escape ^|, ^^, ^&, etc. unless double-quoted, like in "| ^ &".

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

If you want a carriage return (going to the beginning of the line), run just
cw

如果你想要回车(到行首),只运行
cw

So try this from command line:

所以从命令行试试这个:

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

回答by Mark Deven

I made a function out of @arnep 's idea:

我根据@arnep 的想法做了一个函数:

echo|set /p="Hello World"

echo|set /p="Hello World"

here it is:

这里是:

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

Use it with call :SL "Hello There"
I know this is nothing special but it took me so long to think of it I figured I'd post it here.

使用它,call :SL "Hello There"
我知道这没什么特别的,但我花了很长时间才想到它,我想我会在这里发布它。