如何从批处理文件输出中插入换行符?

我想做的事情是:

echo hello\nworld

这将输出:

hello
world

Use:

echo hello
echo:
echo world

Echo hello & Echo .world

这意味着您可以定义& echo。作为换行符的常数\n。


在这里,创建一个.bat文件,其中包含以下内容:

@echo off
REM Creating a Newline variable (the two blank lines are required!)
set NLM=^


set NL=^^^%NLM%%NLM%^%NLM%%NLM%
REM Example Usage:
echo There should be a newline%NL%inserted here.

echo.
pause

您应该会看到如下输出:

There should be a newline
inserted here.

Press any key to continue . . .

显然,您只需要REM语句之间的代码。


当回显某些内容以重定向到文件时,多个回显命令将不起作用。我认为“>>”重定向器是一个不错的选择:

echo hello > temp
echo world >> temp

就像Grimtron建议的那样-这里有一个简单的例子来定义它:

@echo off
set newline=^& echo.
echo hello %newline%world

输出

C:\>test.bat
hello
world

这对我来说很有效,不需要延迟扩展:

@echo off
(
echo ^<html^> 
echo ^<body^>
echo Hello
echo ^</body^>
echo ^</html^>
)
pause

它像这样写输出:

<html>
<body>
Hello
</body>
</html>
Press any key to continue . . .

有一个标准的功能echo:在cmd/bat-files中写入空行,这模拟了cmd-output中的新行:

@echo off
echo line1
echo:
echo line2

or

@echo line1 & echo: & echo line2

上面引用的cmd-file输出:

line1

line2

就像肯的答案一样,只是用了延迟扩展。

setlocal EnableDelayedExpansion
(set \n=^
%=Do not remove this line=%
)

echo Line1!\n!Line2
echo Works also with quotes "!\n!line2"

First a single linefeed character is created and assigned to the \n-variable. This works as the caret at the line end tries to escape the next character, but if this is a Linefeed it is ignored and the next character is read and escaped (even if this is also a linefeed). Then you need a third linefeed to end the current instruction, else the third line would be appended to the LF-variable. Even batch files have line endings with CR/LF only the LF are important, as the CR's are removed in this phase of the parser.

使用延迟展开的优点是,根本不需要进行特殊的字符处理。 Line1%LF%Line2将失败,因为解析器在单个换行处停止解析。

更多解释见 SO:在Vista/DOS批处理(.bat)文件中,长命令拆分为多行 那么:Windows命令解释器(CMD.EXE)如何解析脚本?

编辑:避免回声。

这并没有回答问题,因为问题是关于单个echo可以输出多行。

但是除了其他答案谁建议使用回声。要创建新行,应注意echo。是最糟糕的,因为它非常慢,它可以完全失败,因为cmd.exe搜索一个名为ECHO的文件,并试图启动它。

如果只打印空行,可以使用其中之一

echo,
echo;
echo(
echo/
echo+
echo=

而是回声的使用。, echo\或echo:应该避免,因为它们会非常慢,这取决于脚本执行的位置,比如网络驱动器。


你也可以这样做,

(for %i in (a b "c d") do @echo %~i)

输出将是,

a
b
c d

请注意,当将其放入批处理文件中时,'%'应该加倍。

(for %%i in (a b "c d") do @echo %%~i)

如果有人来这里是因为他们想从MINGW make makefile中回显一个空行,我使用

@cmd /c echo。

简单地使用echo。导致可怕的process_begin: CreateProcess(NULL, echo。,…)失败了。错误消息。

我希望这能帮助到至少一个人:)


可以使用@echo (@echo +[空间]+[不安全空间])

注:不安全空间可用Alt+0160获取

希望能有所帮助。

嗯,你是对的,我需要它在一个Makefile中,它在那里工作得很好。我想我的答案不适合批处理文件…我的坏。


的回声。足够的说。

如果需要在单行中使用&。例如,

echo Line 1 & echo. & echo line 3

输出如下:

Line 1

line 3

现在,假设你想要一些更花哨的东西,……

set n=^&echo.
echo hello %n% world

输出

hello
world

然后当你想在echo语句中添加新行时,只需在其中加入%n%。这更接近于你在各种语言中使用的\n。

分解

Set n=设置变量n等于:

^取消后面的下一个符号:

&表示在同一行上执行另一个命令。我们不关心errorlevel(这是一个echo语句),所以不需要&&。

的回声。继续echo语句。

所有这些都是可行的,因为您实际上可以创建代码变量,并在其他命令中使用它们。它有点像贫民区函数,因为批处理并不是最先进的shell脚本语言。这只是因为批处理对变量的使用很差,没有在int、char、float、字符串等之间自然地进行指定。

如果你很狡猾,你可以让它和其他东西一起工作。例如,使用它来回显一个制表符

set t=^&echo.     ::there are spaces up to the double colon

如果你需要把结果放到一个文件中,你可以使用:

(echo a & echo: & echo b) > file_containing_multiple_lines.txt

Ken和Jeb的解决方案效果很好。

但是新行只生成一个LF字符,我需要CRLF字符(Windows版本)。

为此,在脚本的末尾,我已经将LF转换为CRLF。

例子:

TYPE file.txt | FIND "" /V > file_win.txt
del file.txt
rename file_win.txt file.txt

要批量地开始新一行,你所要做的就是添加“echo[”,像这样:

echo Hi!
echo[
echo Hello!

如果需要在可以传递给变量的字符串中使用著名的\n,可以编写如下Hello.bat脚本所示的代码:

@echo off
set input=%1
if defined input (
    set answer=Hi!\nWhy did you call me a %input%?
) else (
    set answer=Hi!\nHow are you?\nWe are friends, you know?\nYou can call me by name.
)

setlocal enableDelayedExpansion
set newline=^


rem Two empty lines above are essential
echo %answer:\n=!newline!%

通过这种方式,多行输出可以在一个地方准备,甚至在其他脚本或外部文件中,并在另一个地方打印。

The line break is held in newline variable. Its value must be substituted after the echo line is expanded so I use setlocal enableDelayedExpansion to enable exclamation signs which expand variables on execution. And the execution substitutes \n with newline contents (look for syntax at help set). We could of course use !newline! while setting the answer but \n is more convenient. It may be passed from outside (try Hello R2\nD2), where nobody knows the name of variable holding the line break (Yes, Hello C3!newline!P0 works the same way).

上面的例子可以细化为子程序或独立批处理,如调用:mlecho Hi\ i 'm your computer:

:mlecho
setlocal enableDelayedExpansion
set text=%*
set nl=^


echo %text:\n=!nl!%
goto:eof

请注意,额外的反斜杠不会阻止脚本解析\n子字符串。


为什么不使用子字符串/替换空格来echo;?

set "_line=hello world"
echo\%_line: =&echo;%

结果:

hello
world

或者,将\n替换为echo;

set "_line=hello\nworld"
echo\%_line:\n=&echo;%

简单的

set nl=.
echo hello
echo%nl%
REM without space ^^^
echo World

结果:

hello
world

在windows 10的虚拟终端序列中,存在高度控制光标位置的方法。

要定义转义序列0x1b,可以使用以下方法:

@Echo off
 For /f %%a in ('echo prompt $E^| cmd')Do set \E=%%a

在字符串之间输出一个换行符:

<nul set /p "=Hello%\E%[EWorld"

输出n个换行符,其中n被整数替换。

<nul set /p "=%\E%[nE"

Many


注意,这不会在控制台工作,因为它将模拟一个escape键和清除行。

使用这段代码,将<ESC>替换为0x1b转义字符或使用这个Pastebin链接:

:: Replace <ESC> with the 0x1b escape character or copy from this Pastebin:
:: https://pastebin.com/xLWKTQZQ

echo Hello<ESC>[Eworld!

:: OR

set "\n=<ESC>[E"
echo Hello%\n%world!

请注意,所有解决方案使用光标定位根据控制台虚拟终端序列,光标定位与:

Sequence Code Description Behaviour
ESC [ <n> E CNL Cursor Next Line Cursor down <n> lines from current position

只有在没有到达控制台窗口底部时才能工作。

在底部没有空间来向下移动光标,所以它只是向左移动(与CRLF的CR),之前打印的行从它的开始被覆盖。


经过一个不眠之夜,在阅读了这里所有的答案后,在阅读了大量的SS64 > CMD和大量的尝试和错误后,我发现:

(几乎)终极解决方案

博士TL;

... 对于早期采用者。

Important!
Use a text editor for C&P that supports Unicode, e.g. Notepad++!

设置换行环境变量…

... 在当前CMD会话中

Important!
Do not edit anything between '=' and '^'! (There's a character in between though you don't see it. Neither here nor in edit mode. C&P works here.)
:: Sets newline variables in the current CMD session
set \n=​^&echo:
set nl=​^&echo:

... 当前用户

Important!
Do not edit anything between (the second) '' and '^'! (There's a character in between though you don't see it. Neither here nor in edit mode. C&P works here.)
:: Sets newline variables for the current user [HKEY_CURRENT_USER\Environment]
setx \n ​^&echo:
setx nl ​^&echo:

... 对于本地机器

Important!
Do not edit anything between (the second) '' and '^'! (There's a character in between though you don't see it. Neither here nor in edit mode. C&P works here.)
:: Sets newline variables for the local machine [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment]
setx \n ​^&echo: /m 
setx nl ​^&echo: /m 

为什么只是快?

它不适用于在同一打印行中没有配对(开引号和闭引号)的双引号,除非唯一未配对的双引号是文本的最后一个字符,例如:

works: ""echo %\n%...after "newline". Before "newline"...%\n%...after "newline" (paired in each printed line) works: echo %\n%...after newline. Before newline...%\n%...after newline" (the only unpaired double-quote is the last character) doesn't work: echo "%\n%...after newline. Before newline...%\n%...after newline" (double-quotes are not paired in the same printed line) Workaround for completely double-quoted texts (inspired by Windows batch: echo without new line): set BEGIN_QUOTE=echo ^| set /p !=""" ... %BEGIN_QUOTE% echo %\n%...after newline. Before newline...%\n%...after newline"

它适用于完全单引号的文本,如:

echo '%\n%...after newline. Before newline...%\n%...after newline'

附加值:转义字符

Note
There's a character after the '=' but you don't see it here but in edit mode. C&P works here.
:: Escape character - useful for color codes when 'echo'ing
:: See https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences#text-formatting
set ESC=

颜色参见https://imgur.com/a/EuNXEar和https://gist.github.com/gerib/f2562474e7ca0d3cda600366ee4b8a45。

第二个附加价值:轻松获取Unicode字符

通过关键字获取87,461个Unicode字符(AToW)的绝佳页面:https://www.amp-what.com/。

的原因

The version in Ken's answer works apparently (I didn't try it), but is somehow...well...you see: set NLM=^ set NL=^^^%NLM%%NLM%^%NLM%%NLM% The version derived from user2605194's and user287293's answer (without anything between '=' and '^'): set nl=^&echo: set \n=^&echo: works partly but fails with the variable at the beginning of the line to be echoed: > echo %\n%Hello%\n%World! echo & echo:Hello & echo:World! echo is ON. Hello World due to the blank argument to the first echo. All others are more or less invoking three echos explicitely. I like short one-liners.

背后的故事

为了防止set \n=^&echo:在这里的回答中显示空白(并打印其状态),我第一次记住Alt+255用户是在Novell广泛使用网络和使用437和850等代码页的时候。但是0d255/0xFF在现在的Unicode中是大写的大写字母Y。

然后我想起来Unicode中有比普通的0d32/0x20更多的空格,但它们都被认为是空格,并导致与›␣相同的行为。

But there are even more: the zero width spaces and joiners which are not considered as whitespaces. The problem with them is, that you cannot C&P them since with their zero width there's nothing to select. So, I copied one that is close to one of them, the hair space (U+200A) which is right before the zero width space (U+200B) into Notepad++, opened its Hex-Editor plugin, found its bit representation E2 80 8A and changed it to E2 80 8B. Success! I had a non-whitespace character that's not visible in my \n environment variable.


在Ken的回答中添加一个变量,它显示了环境变量的设置值,其中包含新行。

我们使用此方法将错误条件附加到VAR中的字符串中,然后在所有错误检查输出的末尾将所有错误汇总到文件中。

这不是完整的代码,只是一个示例。

@echo off
SETLOCAL ENABLEDELAYEDEXPANSION
:: the two blank lines are required!
set NLM=^


set NL=^^^%NLM%%NLM%^%NLM%%NLM%
:: Example Usage:

Set ErrMsg=Start Reporting:
:: some logic here finds an error condition and appends the error report
set ErrMsg=!ErrMsg!!NL!Error Title1!NL!Description!NL!Summary!NL!

:: some logic here finds another error condition and appends the error report
set ErrMsg=!ErrMsg!!NL!Error Title2!NL!Description!NL!Summary!NL!

:: some logic here finds another error condition and appends the error report
set ErrMsg=!ErrMsg!!NL!Error Title3!NL!Description!NL!Summary!NL!

echo %ErrMsg%
pause
echo %ErrMsg% > MyLogFile.log

日志和屏幕输出看起来像这样…


要回显换行符,请添加一个点。就在回声之后:

echo.