如何从批处理文件输出中插入换行符?
我想做类似的事情:
echo hello\nworld
这将输出:
hello
world
采用:
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 语句之间的代码。
cmd/bat-files 中有一个标准功能echo:
可以写入空白行,它模拟 cmd 输出中的新行:
@echo off
echo line1
echo:
echo line2
或者
@echo line1 & echo: & echo line2
上面引用的 cmd 文件的输出:
line1
line2
像肯的答案,但使用延迟扩展。
setlocal EnableDelayedExpansion
(set \n=^
%=Do not remove this line=%
)
echo Line1!\n!Line2
echo Works also with quotes "!\n!line2"
首先创建一个换行符并将其分配给 \n 变量。
这是因为行尾的插入符号试图转义下一个字符,但如果这是一个换行符,它将被忽略并且下一个字符被读取并转义(即使这也是一个换行符)。
然后您需要第三个换行符来结束当前指令,否则第三行将附加到 LF 变量。
即使批处理文件的行尾以 CR/LF 结尾,也只有 LF 很重要,因为 CR 在解析器的这个阶段被删除。
使用延迟扩展的优点是根本没有特殊字符处理。
echo Line1%LF%Line2
将失败,因为解析器在单个换行符处停止解析。
更多解释
见 SO:Vista/DOS 批处理 (.bat) 文件中
的多行长命令拆分 SO:Windows 命令解释器 (CMD.EXE) 如何解析脚本?
编辑:避免echo.
这不能回答问题,因为问题是关于echo
可以输出多行的单行。
但是,尽管其他答案建议使用echo.
创建新行,但应该注意这echo.
是最糟糕的,因为它非常慢并且可能完全失败,因为 cmd.exe 搜索名为的文件ECHO
并尝试启动它。
对于只打印一个空行,您可以使用其中一个
echo,
echo;
echo(
echo/
echo+
echo=
但是应该避免使用echo.
, echo\
or ,因为它们可能真的很慢,这取决于脚本执行的位置,比如网络驱动器。echo:
echo.
说够了。
如果您需要在一行中使用它,请使用&
. 例如,
echo Line 1 & echo. & echo line 3
将输出为:
Line 1
line 3
现在,说你想要一些更花哨的东西,...
set n=^&echo.
echo hello %n% world
输出
hello
world
然后,%n%
只要你想在 echo 语句中换行,就输入 a 。这更接近您\n
在各种语言中的使用。
分解
set n=
设置变量n
等于:
^
取消下一个符号:
&
意味着在同一行上执行另一个命令。我们不关心错误级别(它是一个大声喊叫的回声语句),所以&&
不需要。
echo.
继续 echo 语句。
所有这些都有效,因为您实际上可以创建代码变量,并在其他命令中使用它们。它有点像 ghetto 函数,因为批处理并不是最先进的 shell 脚本语言。这仅适用于批处理对变量的不良使用,而不是自然地在整数、字符、浮点数、字符串等之间指定。
如果你很狡猾,你可以让它与其他东西一起工作。例如,使用它来回显选项卡
set t=^&echo. ::there are spaces up to the double colon
回显某些内容以重定向到文件时,多个回显命令将不起作用。我认为也许“>>”重定向器是一个不错的选择:
回声你好>温度 回声世界>>温度
如果需要将结果保存到文件中,可以使用:
(echo a & echo: & echo b) > file_containing_multiple_lines.txt
就像 Grimtron 建议的那样 - 这是一个定义它的快速示例:
@echo off
set newline=^& echo.
echo hello %newline%world
C:\>test.bat
hello
world
你也可以这样做,
(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., ...) failed.
错误消息。
我希望这至少可以帮助其他人:)
Ken 和 Jeb 解决方案运行良好。
但是新行仅使用 LF 字符生成,我需要 CRLF 字符(Windows 版本)。
为此,在脚本的最后,我将 LF 转换为 CRLF。
例子:
TYPE file.txt | FIND "" /V > file_win.txt
del file.txt
rename file_win.txt file.txt
如果需要在可以传递给变量的字符串文字中使用著名的 \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!%
这样,多行输出可以在一个地方准备好,甚至在其他脚本或外部文件中,并在另一个地方打印。
换行符保存在换行变量中。它的值必须在echo行展开后被替换,所以我使用setlocal enableDelayedExpansion来启用在执行时展开变量的感叹号。并且执行将\n替换为换行内容(在help set中查找语法)。我们当然可以使用!newline!在设置答案时,但\n更方便。它可能从外部传递(尝试Hello R2\nD2),没有人知道保存换行符的变量的名称(是的,Hello C3!newline!P0工作方式相同)。
上面的示例可以细化为子程序或独立批处理,使用如下call:mlecho Hi\nI'm your comuter
:
:mlecho
setlocal enableDelayedExpansion
set text=%*
set nl=^
echo %text:\n=!nl!%
goto:eof
请注意,额外的反斜杠不会阻止脚本解析 \n 子字符串。
要批量开始一个新行,您所要做的就是添加“echo [”,如下所示:
echo Hi!
echo[
echo Hello!
为什么不使用子字符串/替换空间echo;
?
set "_line=hello world"
echo\%_line: =&echo;%
hello
world
echo;
set "_line=hello\nworld"
echo\%_line:\n=&echo;%
对于具有虚拟终端序列的 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"
许多
请注意,根据控制台虚拟终端序列使用光标定位的所有解决方案,光标定位:
顺序 | 代码 | 描述 | 行为 |
---|---|---|---|
ESC [ <n> E | CNL | 光标下一行 | 从当前位置向下移动 <n> 行 |
仅在未到达控制台窗口底部时才起作用。
在底部没有剩余空间可以向下移动光标,因此它只是向左移动(使用CR
of CRLF
)并且之前打印的行从头开始被覆盖。
经过一个不眠之夜并阅读了此处的所有答案,阅读了很多SS64 > CMD并经过大量尝试和错误后,我发现:
... 对于早期采用者。
重要的! |
---|
使用支持 Unicode 的 C&P 文本编辑器,例如 Notepad++! |
重要的! |
---|
不要编辑 ' ' 和 ' ' 之间的任何内容!= ^ (中间有一个角色,虽然你看不到。这里和编辑模式都没有。C&P 在这里工作。) |
:: Sets newline variables in the current CMD session
set \n=^&echo:
set nl=^&echo:
重要的! |
---|
不要编辑(第二个)之间的任何内容'␣</code>' 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:
重要的! |
---|
不要编辑(第二个)之间的任何内容'␣</code>' 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
它不适用于同一打印行中未配对(打开和关闭)的双引号,除非唯一未配对的双引号是文本的最后一个字符,例如:
作品:(在每条印刷线""echo %\n%...after "newline". Before "newline"...%\n%...after "newline"
中配对)
有效:(echo %\n%...after newline. Before newline...%\n%...after newline"
唯一不成对的双引号是最后一个字符)
不起作用:(echo "%\n%...after newline. Before newline...%\n%...after newline"
双引号不在同一印刷行中配对)
完全双引号文本的解决方法(受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'
笔记 |
---|
' ' 后面有一个字符,= 但您在这里看不到它,但在编辑模式下。C&P 在这里工作。 |
:: Escape character - useful for color codes when 'echo'ing
:: See https://docs.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。
按关键字获取 87,461 个 Unicode 字符 (AToW) 的绝佳页面:https ://www.amp-what.com/ 。
肯的答案中的版本显然有效(我没有尝试过),但不知何故......嗯......你看:
set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
从user2605194和user287293=
的答案派生的版本(在 ' ' 和 ' '之间没有任何内容^
):
set nl=^&echo:
set \n=^&echo:
echo
部分工作,但由于要编辑的行开头的变量而失败:
> echo %\n%Hello%\n%World!
echo & echo:Hello & echo:World!
echo is ON.
Hello
World
由于第一个的空白参数echo
。
所有其他人或多或少都echo
明确地调用了 3 。
我喜欢短的单行字。
为了防止set \n=^&echo:
此处的答案中的建议回显空白(以及打印其状态),我首先记得Alt+255用户是在 Novell 是一个广泛使用的网络并使用437和850之类的代码页时。但是现在 Unicode 中的 0d255/0xFF 是›Ÿ‹(带分音符号的拉丁文小写字母 Y)。
然后我记得Unicode中的空格比普通的 0d32/0x20 多,但它们都被认为是空格并导致与 ›␣‹ 相同的行为。
但还有更多:零宽度空格和不被视为空格的连接符。它们的问题是,你不能对它们进行 C&P,因为它们的宽度为零,没有什么可供选择的。所以,我复制了一个接近其中之一的头发空间(U+200A),它就在零宽度空间(U+200B)之前到 Notepad++,打开它的 Hex-Editor 插件,找到它的位表示E2 80 8A
并更改它到E2 80 8B
. 成功!\n
我有一个在我的环境变量中不可见的非空白字符。
这对我有用,不需要延迟扩展:
@echo off
(
echo ^<html^>
echo ^<body^>
echo Hello
echo ^</body^>
echo ^</html^>
)
pause
它像这样写输出:
<html>
<body>
Hello
</body>
</html>
Press any key to continue . . .
您可以使用@echo
(@echo + [space] + [insecable space])
注意:不可分割的空间可以通过 Alt+0160 获得
希望能帮助到你 :)
[编辑] 嗯,你是对的,我需要它在 Makefile 中,它在那里完美运行。我想我的答案不适用于批处理文件......我的错。
简单的
set nl=.
echo hello
echo%nl%
REM without space ^^^
echo World
结果:
hello
world
请注意,这在控制台中不起作用,因为它会模拟转义键并清除线路。
使用此代码,替换<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!
在肯的答案中添加一个变体,显示环境变量的设置值,其中包含新行。
我们使用这种方法将错误条件附加到 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
日志和屏幕输出如下所示...