如何在批处理文件中使用echo输出换行符?

779
如何在批处理文件输出中插入换行符号?
我想要做这样的事情:
echo hello\nworld

将输出:

hello
world

9
对我很有用。我需要在脚本中运行 echo \n \n | my_app.exe。我运行了 (echo. && echo.) | my_app.exe。 - Vignesh
2
简单方法 "代码开始:" > echo hello&echo world,将给您所需的内容 - prudviraj
2
您可以在单独的一行上插入一个不可见的ASCII字符(255),这将强制产生一个空白新行。按住[alt]键,然后在小键盘上按下255。这将插入chr(255),它是一个空白方块。即"echo (alt+255)"。您只能使用小键盘,而不能使用querty键盘上面的数字键! - jwzumwalt
1
@jwzumwalt,感谢您提供的alt+255建议,在命令行上非常有效。 - K Vij
printf "\n\n\n" - Mark
显示剩余3条评论
27个回答

8

如果有人来到这里是因为想要在MINGW make makefile中回显一个空行,我使用了

@cmd /c echo.

仅使用echo.会导致可怕的process_begin: CreateProcess(NULL, echo., ...) failed.错误消息。

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


不确定是否在使用讽刺 :P - Wayne Uroda
请查看您的收件箱以获取答案 :D - Mesalcode

6
为了换行,需要在echo后面添加一个点.
echo.

3
回答一个15年前的问题应该不包含任何新东西,但是您的答案在这里之前已经被多次提供过了。顺便说一下,“echo .”不是一个好的答案,因为它有缺点。 - jeb

4

经过一夜的不眠和阅读此处的所有答案,阅读了大量SS64 > CMD并尝试了很多次错误后,我找到了:

(几乎)终极解决方案

TL;DR

... 对于早期采用者。

重要!
使用支持Unicode的文本编辑器进行复制和粘贴,例如Notepad++!

设置换行符环境变量...

...在当前CMD会话中

重要!
不要编辑“= ”和“^”之间的任何内容!(虽然这两个符号之间有一个字符,但您看不到它。无论是在这里还是在编辑模式中都是如此。在这里进行复制和粘贴是可以工作的。)
:: Sets newline variables in the current CMD session
set \n=​^&echo(
set nl=​^&echo(

...对于当前用户

重要提示!
不要编辑(第二个)''和'^'之间的任何内容!(虽然这两个字符之间有一个字符,但您在此处或编辑模式下都看不到它。复制和粘贴在此处有效。)
:: Sets newline variables for the current user [HKEY_CURRENT_USER\Environment]
setx \n ​^&echo(
setx nl ​^&echo(

...针对本地机器

重要提示!
不要编辑位于(第二个)''和'^'之间的任何内容!(尽管中间有一个字符,但您无法看到它。无论在此处还是在编辑模式下都是如此。在此处可以使用复制和粘贴功能。)
:: 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'

增加的价值: 转义字符

注意事项
在“=”后面有一个字符,但在此处看不到,只有在编辑模式下才能看到。复制和粘贴在这里有效。
:: 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/EuNXEarhttps://gist.github.com/gerib/f2562474e7ca0d3cda600366ee4b8a45

第二个增值点:轻松获取Unicode字符

一个很好的页面,可以通过关键词(AToW)获取87,461个Unicode字符: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:时出现空白(并打印其状态),我首先想起了那些使用437850等代码页面的Novell网络时代的Alt+255用户。但是0d255 / 0xFF现在在Unicode中是›Ÿ‹(带分音符的拉丁小写字母Y)

然后我记得Unicode中有更多的空格,而不仅仅是普通的0d32 / 0x20,但它们都被视为空格,并导致与›␣‹相同的行为。

但还有更多:零宽度空格和连接符不被视为空格。它们的问题在于,由于它们的零宽度,您无法复制和粘贴它们,因为没有内容可以选中。所以,我复制了一个接近它们之一的"hair space"(U+200A),它位于"zero width space"(U+200B)之前,然后打开了Notepad++的Hex-Editor插件,找到了它的位表示E2 80 8A并把它改为E2 80 8B。成功了!我得到了一个不在我的\n环境变量中可见的非空格字符。


在标准代码页437上,这行代码:echo Hello%\n%world将会输出HelloΓÇï<换行>World,但是当执行chcp 65001时就可以正常工作。 - Gerhard
@Gerhard难怪,CP 437不是Unicode代码页。我在Windows 7上也看到了同样的情况。哪个标准?Windows 7及之前的版本?Unicode现在已经有30年历史了。我认为它现在甚至应该被视为标准。 - Gerold Broser
我新安装的Windows 10专业版系统中的代码页是437。 - Gerhard
@Gerhard 是的,微软在他们的操作系统中数十年忽略了 Unicode。自从 Win 8 以来,我只在必须使用它们时才与它们合作。 - Gerold Broser
set \n=^&echo: 只是一个弱的技巧,它并不是换行符的定义。或者尝试 set multiline=Line1%\n%Line2 然后 echo ### !multiline!。应该使用Ken的答案或其延迟扩展变体。 - jeb

3

Ken and Jeb solutions的表现不错。

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

因此,在脚本结束时,我将LF转换为CRLF。

示例:

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

3
如果需要在可以传递给变量的字符串文字中使用著名的换行符,则可以像下面的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 子字符串。

2
你基本上正在执行与Jeb上面的答案相同的操作。 - Squashman
我读到的答案非常有帮助,但我需要调用一个解析 \n 的脚本或子程序,以避免在每个地方都实现这个技巧。这需要完善解决方案,我分享了这个改进。希望它没有伤害到任何动物。 - Tomator
这个答案很有用,但是由于感叹号被解释了,你的参数如何显示一个字面上的感叹号呢?我尝试通过在前缀中加入一个或两个插入符来转义它们,但是没有成功。 - Florent Angly
@FlorentAngly,试试这个:set ex=!setlocal enableDelayedExpansionecho shout!ex! - Tomator

2

要在批处理中开始新行,您只需添加"echo["即可:

echo Hi!
echo[
echo Hello!

6
当存在以echo[.bat命名的文件时,它会运行缓慢且失败。 - jeb
什么?它应该立即生效,并且只需删除echo[.bat文件。 - PryroTech
3
这句话的意思是“它与 echo 命令的语法几乎完全相同”。 - PryroTech
7
是的,“echo。”也是一个不好的解决方案。 - jeb
2
正如之前的答案所示,这将首先尝试在路径上定位文件,这会导致它变得非常缓慢。echo.也是如此。期望用户删除其系统上的文件,仅因为您的脚本需要一个换行符,这听起来对我来说并不是一个好的设计。 - Abel

2
请注意,所有使用控制台虚拟终端序列,光标定位的解决方案都需要根据以下格式进行定位:
序列 代码 描述 行为
ESC [ <n> E CNL 光标下移一行 从当前位置向下移动<n>行
只有在控制台窗口底部未到达时才能正常工作。
当到达底部时,就没有空间可以将光标向下移动,因此它会向左移动(使用CRCRLF),并且之前打印的行将被从其开头覆盖。

2

对于具备 虚拟终端序列 的 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"

许多

请查看我在此处对@Vopel答案的评论,其中提到ESC [ <n> E(光标下移n行)只有在未到达控制台窗口底部时才有效。 - Gerold Broser

2
为什么不使用substring/replace空格来echo;
set "_line=hello world"
echo\%_line: =&echo;%
  • 结果:
hello
world
  • 或者,将 \n 替换为 echo;
set "_line=hello\nworld"
echo\%_line:\n=&echo;%

虽然这个方法可能可行(我没有测试过),但是将你的(可能有很多)文本分配给环境变量并每次都执行字符串替换相当麻烦。 - Gerold Broser
@GeroldBroser 好的,那我们测试一下,看看哪些可以注释掉如果它不起作用? - Io-oI
@GeroldBroser 关于什么是不方便的和什么是方便的,这取决于每个人的需求、能力和知识。我可以分配变量、替换和多个子字符串到许多环境变量中,而不必写出每一个。 - Io-oI
为什么之前没有人评论过这个问题? 哪个答案不会引起您同等的担忧? - Io-oI

1

14年后,我建议使用PowerShell。

你甚至很可能只需要将文件扩展名从.bat改为.ps1就可以让它正常工作。

然后,你可以使用:

echo "Hello`nWorld"

# or even

echo Hello`nWorld

在Win10上测试通过。

您也可以使用echo "Hello`r`nWorld"来生成Windows类型的换行符。

来源:https://devblogs.microsoft.com/scripting/powertip-new-lines-with-powershell/,它说“使用 `n 字符”。


其他答案和评论中的许多混淆是由于echo在Windows和Linux上都可用。对于Linux,您可以简单地使用echo "Hello\nWorld"在大多数发行版上获得相同的结果。
但是,在Linux脚本中仍建议使用printf

将语言切换来解决一个小问题是毫无意义的 - jeb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接