通过Windows批处理文件在多行中拆分长命令

如何将长命令拆分到批处理文件中的多行?

546940 次浏览

您可以使用插入符号^拆分长行,只要您记住插入符号和它后面的换行符已完全删除。因此,如果您要拆线时应该有一个空格,请包含一个空格。更多关于下面。

示例:

copy file1.txt file2.txt

将写成:

copy file1.txt^file2.txt

插入符号的规则是:

行尾的插入符号,附加下一行,附加行的第一个字符将被转义。

您可以多次使用插入符号,但完整行不得超过~8192个字符的最大行长度(Windows XP、Windows Vista和Windows 7)。

echo Test1echo one ^two ^three ^four^*--- Output ---Test1one two three four*
echo Test2echo one & echo two--- Output ---Test2onetwo
echo Test3echo one & ^echo two--- Output ---Test3onetwo
echo Test4echo one ^& echo two--- Output ---Test4one & echo two

要抑制下一个字符的转义,您可以使用重定向。

重定向必须在插入符号之前。但是在插入符号之前存在一个重定向的好奇心。

如果在插入符号处放置标记,则标记将被删除。

echo Test5echo one <nul ^& echo two--- Output ---Test5onetwo

echo Test6echo one <nul ThisTokenIsLost^& echo two--- Output ---Test6onetwo

并且也可以将嵌入换行符插入字符串:

setlocal EnableDelayedExpansionset text=This creates ^
a line feedecho Test7: %text%echo Test8: !text!--- Output ---Test7: This createsTest8: This createsa line feed

空行对成功很重要。这只适用于延迟扩展,否则在换行后忽略行的其余部分。

它有效,因为行尾的插入符号忽略下一个换行符并转义下一个字符,即使下一个字符也是换行符(在这个阶段总是忽略回车)。

(这基本上是重写了Wayne的答案但随着插入符号周围的混乱得到了澄清。所以我把它作为一个CW发布。我并不羞于编辑答案,但完全重写它们似乎不合适。)

你可以用插入符号(^)拆分长行,只要记住插入符号和它后面的换行符被完全移除来自命令,所以如果你把它放在需要空格的地方(比如参数之间),一定要包括空格(要么在^之前,要么在下一行的开头——后一种选择可能有助于更清楚它是一个延续)。

⚠注意:下一行的第一个字符被转义。因此,如果它带有任何特殊含义(如&|),该含义将丢失,它将被解释为纯文本字符(参见底部的最后一个示例)。

示例:(全部在Windows XP和Windows 7上测试)

xcopy file1.txt file2.txt

可以写成:

xcopy^file1.txt^file2.txt

xcopy ^file1.txt ^file2.txt

甚至

xc^opy ^file1.txt ^file2.txt

(最后一个有效,因为xc^之间没有空格,下一行的开头也没有空格。所以当您删除^和换行符时,您会得到…xcopy。)

为了易读性和理智,最好只在参数之间中断(确保包含空格)。

确保^没有批处理文件中的最后一件事,就像这似乎是个大问题一样。

以下是下一行开头的字符转义示例:

xcopy file1.txt file2.txt ^& echo copied successfully

这将不起作用,因为&将被转义并失去其特殊含义,从而将所有“file1.txtfile2.txt和回声复制成功”作为参数发送到xcopy,从而导致错误(在本例中)。

为了规避,添加一个空格在下一行的开头。

然而,在for循环的值中间拆分似乎不需要插入符号(实际上尝试使用插入符号将被视为语法错误)。例如,

for %n in (hellobye) do echo %n

请注意,在你好之后或再见之前甚至不需要空间。

多个命令可以放在括号中并分布在许多行中;所以像echo hi && echo hello这样的东西可以这样放:

( echo hiecho hello )

变量也可以帮助:

set AFILEPATH="C:\SOME\LONG\PATH\TO\A\FILE"if exist %AFILEPATH% (start "" /b %AFILEPATH% -option C:\PATH\TO\SETTING...) else (...

我还注意到插入符号(^),if条件符号喜欢它们只在存在空格时才跟随:

if exist ^

虽然carret将是更好的方式来做到这一点,这里还有一种使用宏的方法,它通过传递的参数构造命令:

@echo off::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::set "\{\{=setlocal enableDelayedExpansion&for %%a in (" & set "}}="::end::" ) do if "%%~a" neq "::end::" (set command=!command! %%a) else (call !command! & endlocal)":::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
%\{\{%echo"command"writtenon afew lines%}}%

命令在没有插入符号的情况下更容易阅读,但使用特殊符号(例如括号、重定向等)会破坏它。因此,您可以在更简单的情况下这样做。尽管您仍然可以将参数用双引号括起来

在搜索“如何拆分一个长的DOS批处理文件行”时,我没有找到的一件事是如何拆分包含长引用文本的内容。事实上,它在上面的答案中已经涵盖了,但并不明显。使用插孔来逃避它们。例如

myprog "needs this to be quoted"

可以写成:

myprog ^"needs this ^to be quoted^"

但是要小心在用插入符号结束一行后用插入符号开始一行-因为它会以插入符号的形式出现…?:

echo ^"^needs this ^to be quoted^^"

->"需要引用这个^"