如何在批处理文件中回显换行符?
Posted
技术标签:
【中文标题】如何在批处理文件中回显换行符?【英文标题】:How can I echo a newline in a batch file? 【发布时间】:2010-09-13 01:34:43 【问题描述】:如何从批处理文件输出中插入换行符?
我想做这样的事情:
echo hello\nworld
哪个会输出:
hello
world
【问题讨论】:
对我有用。我必须回声 \n \n | my_app.exe 在脚本中。我做了(回声。&&回声。)| my_app.exe Easy Approach "代码开始:" > echo hello&echo world ,会给你你需要的东西 您可以在单独的行上插入一个不可见的 ascii chr(255),这将强制一个空白的新行。按住 [alt] 键并按小键盘上的 255。这将插入 chr(255) 这是一个空白方块。即“echo (alt+255)” 您只能使用小键盘,不能使用 querty 键盘顶部的数字! 正如一半的计算机维修是插入并打开它,一半的软件开发是我所说的空间工程。我们需要我们的空白行。 @jwzumwalt 感谢您的 alt+255 建议,在命令行上效果很好 【参考方案1】:用途:
echo hello
echo:
echo world
【讨论】:
是否可以在单个 echo 语句中提供字符串? 为什么需要用一个echo语句来做;拥有另一个有什么坏处? @Rob,我刚遇到这个问题,但这些都不起作用。在我的示例中,您需要在单个语句中回显。我正在从 html 生成一些 tex 文件并使用echo "Makefile contents (which has \n)" > Makefile
生成一个 Makefile 有多个回声,它不会工作
使用 &(或 &&)在单个语句中执行它们:例如,将“hello\nworld”放入 txt 文件:(echo hello & echo world) >> ./test.txt
对于文件的多行输出,为什么不直接执行以下操作? echo line 1 > Makefile
然后是 echo line 2 >> Makefile
。使用>>
会导致将输出附加到文件中,这正是您在这种情况下需要的行为。【参考方案2】:
echo hello & echo.world
这意味着您可以将& echo.
定义为换行符\n
的常量。
【讨论】:
该示例不需要句点,但您确实需要一个句点来回显一个空白的空行:echo. && echo hello && echo. && echo world
你能用一个回声来做到这一点,以便它可以被重定向到一个文件吗?
@Shahbaz - $ (echo Hello && echo World) > ./File.txt
“回声”中的句号。永远不会停止让我惊讶。它已经过时了,但我总是忘记点必须与命令名称严格连接,中间不能有空格。你的帖子没有错误,我写这个只是为了提醒:“echo”。 != “回声。” !
@quetzalcoatl,它变得更加陌生。除了点之外的其他字符也可以。 SS64 说更好的语法是 echo(
以提高性能(仍然没有空间提醒你)。在ECHO. FAILS to give text or blank line - Instead use ECHO/ 进一步讨论其他角色及其优点/缺点【参考方案3】:
在这里,创建一个包含以下内容的 .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 语句之间的代码。
【讨论】:
非常令人印象深刻,你能花时间解释一下 set NL=^^^%NLM%%NLM%^%NLM%%NLM% 是如何工作的吗?我无法完全理解它 @andy 我认为 +8 评论值得提问:***.com/questions/6379619/… 这是一个很好的例子来证明 cmd.exe 和 Windows 批处理文件是完全疯狂的! 自我注意:“set NLM=^”行必须在 CARET 之后没有任何内容,必须在它之后有 2 个空行。 查看我的答案以获得更简单的方法。set nl=^&echo.
,然后只是 echo hello %nl% world
产生相同的效果。【参考方案4】:
当回显某些内容以重定向到文件时,多个回显命令将不起作用。我认为也许“>>”重定向器是一个不错的选择:
回声你好>温度 回声世界>>温度【讨论】:
第一个示例,使用“>”,将创建一个新文件,第二个示例,使用“>>”,将附加到现有文件(如果它不存在,则创建它)。(echo hello && echo world) > temp
Nathan J. Brauer 在对(当前)接受的答案作品的评论中提到。【参考方案5】:
就像 Grimtron 建议的那样 - 这是一个定义它的简单示例:
@echo off
set newline=^& echo.
echo hello %newline%world
输出
C:\>test.bat
hello
world
【讨论】:
它实际上会在“world”之后回显一个额外的换行符 @blue 尾随换行符似乎是批处理文件本身的功能。如果您重复echo hello %newline%world
行,则两者之间没有空格。
echo "Hello %newline% world"
失败,因为它在引号内。因为它不是一个真正的换行符。
我到处都可以看到它,它具有误导性/混淆性,当然,与真正的换行版本相比,效率非常低。
@HaxAddict1337 哪个是“真正的换行版本”?【参考方案6】:
这对我有用,不需要延迟扩展:
@echo off
(
echo ^<html^>
echo ^<body^>
echo Hello
echo ^</body^>
echo ^</html^>
)
pause
它这样写输出:
<html>
<body>
Hello
</body>
</html>
Press any key to continue . . .
【讨论】:
-1echo asdf >myfile.txt
将产生完全相同的结果。 echo
在字符串末尾追加一个换行符。
很好的答案,是唯一一个认识到使用括号换行的价值的人。我相信这就是 DOS 的制造者希望你这样做的方式。【参考方案7】:
在 cmd/bat-files 中有一个标准功能 echo:
可以写入空白行,它在您的 cmd 输出中模拟一个新行:
@echo off
echo line1
echo:
echo line2
或
@echo line1 & echo: & echo line2
上面引用的cmd文件的输出:
line1
line2
【讨论】:
事实上,任何 UNUSED 特殊字符都可以工作。我总是鼓励使用 / 因为斜杠是命令选项的标准字符。另外,我总是批评微软有人不幸选择使用点,因为命令:echo.com 会根据 MS-DOS/Windows 批处理命令处理器的版本给出不同的结果。 唯一始终有效的版本是echo(
。看起来它可能会导致问题,但它实际上工作得很好。所有其他形式至少有一种情况,命令无法按预期执行。
@naxa - 没有任何官方信息,只是由几批黑客得出的集体知识。目标是拥有可用于 ECHO 任何值的语法,包括任何值,并且永远不必担心得到预期之外的任何值。我所知道的最好的总结是dostips.com/forum/viewtopic.php?p=4554#p4554。这有点让你悬而未决,但没有人想出ECHO(
失败的场景。
@Pacerier - 每个建议都有失败的例子。仔细阅读dostips.com/forum/viewtopic.php?p=4554#p4554。
@Pacerier 这里有足够的 echo 来解决一个独立的问题。也许类似于“哪些字符可以立即跟随echo
,它们的作用是什么?”【参考方案8】:
类似于 Ken 的回答,但使用了延迟扩展。
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:Long commands split over multiple lines in Vista/DOS batch (.bat) fileSO:How does the Windows Command Interpreter (CMD.EXE) parse scripts?
编辑:避免echo.
这没有回答问题,因为问题是关于可以输出多行的单个echo
。
但尽管其他答案建议使用echo.
创建新行,但应该注意echo.
是最糟糕的,因为它非常慢并且可能完全失败,因为 cmd.exe 搜索一个名为ECHO
的文件并尝试启动它。
如果只打印一个空行,您可以使用其中一个
echo,
echo;
echo(
echo/
echo+
echo=
但应避免使用echo.
、echo\
或echo:
,因为它们可能非常慢,具体取决于脚本执行的位置,例如网络驱动器。
【讨论】:
如果您将带有换行符的字符串作为参数传递给批处理子例程,例如call :pause line1!\n!line2
,以setlocal EnableDelayedExpansion
开始子程序并以setlocal DisableDelayedExpansion
结束它,以防止换行符被过早解释。
+1 用于演员阵容echo,
echo;
echo(
echo/
echo+
echo=
和流氓画廊echo.
echo\
@98765434@。现在,如果你要解释为什么这些工作,我会欠你一杯免费啤酒。
你能把换行符单独放到 NEWLINE.bat 脚本中吗?
@johnywhy 是的,将代码移动到newline.bat
可能带有echo(!\n!
@jeb 你是说我从 .bat 文件中使用它时必须使用 open-paren 吗?近亲去哪儿了? echo(!\n!
我的意图是在每个想要使用您的方法的批处理文件的顶部调用外部 setup_newline.bat。或者,更好的是,只需将newline
放在我需要换行符的地方,然后让newline
调用newline.bat
,它会返回!\n!
【参考方案9】:
你也可以这样做,
(for %i in (a b "c d") do @echo %~i)
输出将是,
a
b
c d
注意,当它被放入批处理文件时,'%' 应该加倍。
(for %%i in (a b "c d") do @echo %%~i)
【讨论】:
如果您想回显 & 而不是换行符,此解决方案也适用。 我想我发现了一个错误:*
char
这是一个不必要的复杂echo a & echo b & echo c d
,并没有用echo a sentence that contains\na newline identifier in it
回答问题。当然,可以写for %%i in ("a sentence that contains" "a newline in it") do @echo %%~i
,但真的吗?【参考方案10】:
如果有人来这里是因为他们想从 MINGW make makefile 中回显一个空行,我使用了
@cmd /c echo.
简单地使用echo.
会导致可怕的process_begin: CreateProcess(NULL, echo., ...) failed.
错误消息。
我希望这至少可以帮助其他人:)
【讨论】:
不确定是否讽刺:P 通过查看您的收件箱找出答案:D【参考方案11】:你可以使用@echo
(@echo + [空格] + [不可分割的空格])
注意:不可分割的空间可以通过Alt+0160获得
希望对你有帮助:)
[edit] 嗯,你是对的,我需要它在 Makefile 中,它在那里完美运行。我想我的答案不适用于批处理文件......我的错。
【讨论】:
我得到了ECHO ist eingeschaltet (ON).
不是空行,在 cmd 提示符下尝试过
这是一个不间断的空格,而不是换行符。【参考方案12】:
echo.
说得够多了。
如果您需要在一行中使用它,请使用&
。例如,
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
等于:
^
清空下一个符号:
&
表示在同一行执行另一个命令。我们不关心错误级别(它是一个大声喊叫的回声语句),所以不需要&&
。
echo.
继续 echo 语句。
所有这些都有效,因为您实际上可以创建代码变量,并在其他命令中使用它们。它有点像 ghetto 函数,因为批处理并不是最先进的 shell 脚本语言。这仅适用于批处理对变量的不良使用,而不是自然地在整数、字符、浮点数、字符串等之间指定。
如果你很狡猾,你可以让它与其他东西一起工作。例如,使用它来回显一个选项卡
set t=^&echo. ::there are spaces up to the double colon
【讨论】:
不要使用echo.
,因为它首先尝试使用该名称查找文件。使用其他标点符号,例如echo,
当然会失败,echo %n%hello%n%world
→ echo & echo:hello & echo:world
。【参考方案13】:
如果需要将结果放到文件中,可以使用:
(echo a & echo: & echo b) > file_containing_multiple_lines.txt
【讨论】:
【参考方案14】:Ken 和 Jeb 解决方案效果很好。
但新行仅使用 LF 字符生成,我需要 CRLF 字符(Windows 版本)。
为此,在脚本的最后,我已将 LF 转换为 CRLF。
例子:
TYPE file.txt | FIND "" /V > file_win.txt
del file.txt
rename file_win.txt file.txt
【讨论】:
【参考方案15】:要批量开始新行,只需添加“echo[”,如下所示:
echo Hi!
echo[
echo Hello!
【讨论】:
速度很慢,当存在名称为echo[.bat
的文件时会失败
什么?它应该可以立即工作,并且只需删除 echo[.bat 文件。
它与 echo 几乎完全相同。语法。
是的,echo.
也是一个糟糕的解决方案。
从之前的答案中可以看出,这将首先尝试在路径上找到一个文件,这会导致它非常慢。 echo.
也是如此。期望您的脚本的用户仅仅因为您的脚本需要换行符而删除他们系统上的文件,这对我来说听起来不是一个好的设计。【参考方案16】:
如果需要在可以传递给变量的字符串文字中使用著名的 \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!%
这种方式可以在一个地方准备多行输出,甚至在其他脚本或外部文件中,并在另一个地方打印。
换行符保存在 newline 变量中。它的值必须在 echo 行展开后替换,因此我使用 setlocal enableDelayedExpansion 来启用在执行时展开变量的感叹号。并且执行将 \n 替换为 newline 内容(在 help set 中查找语法)。我们当然可以在设置 answer 时使用 !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 子字符串。
【讨论】:
你基本上和上面 Jeb 的回答一样。 我在上面阅读的答案非常有帮助,但我需要调用一个脚本 od 子例程来解析 \n 所以我会避免在任何地方实现这个技巧。这需要改进一个解决方案,我分享了这个改进。希望它不会伤害任何动物。 这个答案很有用,但是由于感叹号被解释了,你的论点怎么能显示一个乱七八糟的感叹号?我尝试通过添加一个或两个插入符号来转义它们,但它不起作用。 @FlorentAngly,试试这个:set ex=!
setlocal enableDelayedExpansion
echo shout!ex!
【参考方案17】:
此解决方案有效(已测试):
type nul | more /e /p
这会将独立的换行转换为回车换行组合。
【讨论】:
但这如何在文本之间添加换行符?问题是关于echo hello \n world
对我投反对票。这不是问题的答案【参考方案18】:
为什么不对echo;
使用子字符串/替换空格?
set "_line=hello world"
echo\%_line: =&echo;%
结果:
hello
world
或者,将 \n 替换为 echo;
set "_line=hello\nworld"
echo\%_line:\n=&echo;%
【讨论】:
虽然这可能有效(我没有测试过),但将(可能很多)文本分配给环境变量并每次都执行字符串替换是相当不方便的。 @GeroldBroser 好的,如何测试并查看如果不起作用可以评论什么? @GeroldBroser 关于什么不方便,什么不方便。这取决于每个人及其需求、能力和知识,我可以在许多 env var 中分配变体、替换和几个子字符串,而不必逐个编写。 为什么以前没有人评论过这个?哪个答案不会给您带来同样的担忧?【参考方案19】:简单
set nl=.
echo hello
echo%nl%
REM without space ^^^
echo World
结果:
hello
world
【讨论】:
与this 13 years old answer的区别在哪里?您的答案很复杂,没有必要。和其他 solution 一样,它没有回答如何使用单个 echo 来解决的问题【参考方案20】:对于带有virtual terminal sequences 的 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"
很多
【讨论】:
见my comment to @Vopel's answer herein 和ESC [ <n> E
的简历(光标下一行 - 光标从当前位置向下 请注意,这在控制台中不起作用,因为它会模拟转义键并清除线路。
使用此代码,将 <ESC>
替换为 0x1b 转义字符或使用 this Pastebin link:
:: 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!
【讨论】:
只要你的命令行没有到达控制台窗口的底部,它就可以工作!然后只显示world!
,因为在底部没有剩余空间可以向下移动光标,所以它只是向左移动(使用CRLF
的CR
)并覆盖Hello
。证明:用echo Hello my%\n%world!
world!my
显示。无论如何,供参考:Console Virtual Terminal Sequences, Cursor Positioning.
该死,你是对的。真令人失望。【参考方案22】:
请注意,根据Console Virtual Terminal Sequences, Cursor Positioning 使用光标定位的所有解决方案:
Sequence | Code | Description | Behaviour |
---|---|---|---|
ESC [ <n> E | CNL | Cursor Next Line | Cursor down <n> lines from current position |
仅在未到达控制台窗口底部时工作。
在底部没有剩余空间可以向下移动光标,所以它只是向左移动(使用CRLF
的CR
)并且之前打印的行从头开始被覆盖。
【讨论】:
【参考方案23】:经过一个不眠之夜,阅读了这里的所有答案,阅读了很多SS64 > CMD,经过很多尝试和错误,我发现:
(几乎)终极解决方案
TL;DR
...对于早期采用者。
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
为什么差不多?
它不适用于在同一打印行中未配对(打开和关闭)的双引号,除非唯一未配对的双引号是文本的最后一个字符,例如:
作品:""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'
附加值:转义字符
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://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。
第二个附加值:轻松获取 Unicode 字符
通过关键字获取 87,461 个 Unicode 字符 (AToW) 的绝佳页面:https://www.amp-what.com/。
原因
Ken's answer 中的版本显然有效(我没有尝试过),但不知何故……嗯……你看:
set NLM=^
set NL=^^^%NLM%%NLM%^%NLM%%NLM%
派生自user2605194 和user287293 答案的版本(在'=
' 和'^
' 之间没有任何内容):
set nl=^&echo:
set \n=^&echo:
部分工作但失败,行首的变量为echo
ed:
> echo %\n%Hello%\n%World!
echo & echo:Hello & echo:World!
echo is ON.
Hello
World
由于第一个 echo
的参数为空白。
所有其他人都或多或少地调用了三个echo
s。
我喜欢短的单行字。
背后的故事
为了防止此处的答案中建议的set \n=^&echo:
回显空白(以及打印其状态),我首先记得 Alt+25 5 用户,当时 Novell 是一个广泛使用的网络,并且使用了像 437 和 850 这样的代码页。但是现在 Unicode 中的 0d255/0xFF 是 ›Ÿ‹ (Latin Small Letter Y with diaeresis)。
然后我记得Unicode 中有more spaces,而不是普通的 0d32/0x20,但它们都被认为是空格,并导致与 ›␣‹ 相同的行为。
但还有更多:零宽度空格和连接符,它们不被视为空格。它们的问题是,你不能对它们进行 C&P,因为它们的宽度为零,没有什么可供选择的。所以,我复制了一个接近其中之一的 头发空间 (U+200A),它就在 零宽度空间 (U+200B) 之前到 Notepad++ ,打开其 Hex-Editor 插件,找到其位表示 E2 80 8A
并将其更改为 E2 80 8B
。成功!我的\n
环境变量中有一个不可见的非空白字符。
【讨论】:
在标准代码页437
这一行:echo Hello%\n%world
将回显 HelloΓÇï
World
但在执行 chcp 65001
时有效set \n=^&echo:
只是一个弱破解,它不是换行定义。或者尝试set multiline=Line1%\n%Line2
然后echo ### !multiline!
。应该使用 Ken 的答案或它的延迟扩展变体。【参考方案24】:
向 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
日志和屏幕输出如下所示...
【讨论】:
如果您使用延迟扩展,我看不出有任何理由仍然使用带有换行符的百分比扩展。使用延迟扩展,您只需要一个简单的 NL 定义,变量的回声也很简单。以上是关于如何在批处理文件中回显换行符?的主要内容,如果未能解决你的问题,请参考以下文章
从 Windows 批处理 (.bat) 脚本中回显带有 Unix 行尾的文本