如何在批处理文件中将长命令拆分为多行?
可以使用符号^
来分割长行,只要记住符号和随后的换行符号都会完全被移除。所以,如果你在分割行的位置需要有一个空格,就需要包含一个空格。(以下链接提供更多信息。)
示例:
copy file1.txt file2.txt
将被书写为:
copy file1.txt^
file2.txt
插入符号的规则是:
在行末使用插入符号(^),会将下一行添加到当前行,被添加行的第一个字符将被转义。
可以多次使用插入符号,但是整行字符数不能超过最大长度限制,约为8192个字符(适用于Windows XP,Windows Vista和Windows 7)。
echo Test1
echo one ^
two ^
three ^
four^
*
--- Output ---
Test1
one two three four*
echo Test2
echo one & echo two
--- Output ---
Test2
one
two
echo Test3
echo one & ^
echo two
--- Output ---
Test3
one
two
echo Test4
echo one ^
& echo two
--- Output ---
Test4
one & echo two
为了禁止转义下一个字符,您可以使用重定向。echo Test5
echo one <nul ^
& echo two
--- Output ---
Test5
one
two
echo Test6
echo one <nul ThisTokenIsLost^
& echo two
--- Output ---
Test6
one
two
而且还可以在字符串中嵌入换行符:
setlocal EnableDelayedExpansion
set text=This creates ^
a line feed
echo Test7: %text%
echo Test8: !text!
--- Output ---
Test7: This creates
Test8: This creates
a line feed
空行对于成功很重要。只有在延迟扩展时才起作用,否则在换行符后面忽略行的其余部分。
它有效的原因是行末的插入符号会忽略下一个换行符并转义下一个字符,即使下一个字符也是换行符(回车符在此阶段始终被忽略)。
copy ^[newline]"file1.txt" ^[newline]"file2.txt"
无法正常工作!我不得不添加一个空格:copy ^[newline] "file1.txt" ^[newline] "file2.txt"
。 - Alexander Gelbukh...附加行的第一个字符将被转义。
您可以使用空格或在 要抑制下一个字符的转义,您可以使用重定向。...
中描述的解决方案。 - jeb你可以使用插入符号 (^
) 来分隔长行,但请记住,插入符号和其后的换行符 将被完全删除,因此如果您将其放在需要空格的位置(例如参数之间),请确保同时包含空格(可以在 ^
前面或下一行的开头添加空格 —— 后者的选择可能有助于使它更清晰地表示为续行)。
⚠ 注意:下一行的第一个字符是转义的。因此,如果它带有任何特殊含义(如 &
或 |
),那么这个含义将丢失,并且它将被解释为纯文本字符(请参见底部的最后一个示例)。
示例:(在 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.txt file2.txt & echo copied successfully”全部作为参数发送给xcopy
,导致错误(在此示例中)。
为了规避这个问题,在下一行开头添加一个空格。
(这基本上是Wayne's answer的重写,但消除了关于插入符的混淆。所以我把它发布为CW。我不介意编辑答案,但完全重写它们似乎不合适。)
多个命令可以被放在括号中并分散在多行上;所以像echo hi && echo hello
这样的命令可以像这样放置:
多个命令可以被放在括号中并分散在多行上;所以像echo hi && echo hello
这样的命令可以像这样放置:
( echo hi
echo 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 ^
cmd1.bat && cmd2.bat
这一行与括号形式不同:仅当 cmd1.bat
成功执行(而且没有设置 %errorcode%
)时,才会执行 cmd2.bat
。后者则是无条件执行。有点出乎意料的是(至少对我来说),显然你不能在换行前使用两者的组合,即在行末添加 &&
。 - Paul Michalik然而,似乎在for循环的值的中间进行分割并不需要使用插入符(实际上尝试使用插入符会被视为语法错误)。例如,
for %n in (hello
bye) do echo %n
for
语法的一部分:在“for-set”中元素的分隔符为 空格、逗号、分号、等号、制表符和换行符。 - Aacinifor %n in (hello bye) do (
echo %n
echo %n
)
- Mohammed Safwat当我搜索“如何分割长的DOS批处理文件行”时,我没有找到如何分割包含长引用文本的内容。
实际上,以上的答案已经覆盖了这一点,但并不明显。使用Caret来转义它们。
例如:
myprog "needs this to be quoted"
可以写成:
myprog ^"needs this ^
to be quoted^"
但要注意,在以插入符号结尾的行后开始一行,因为它将输出为插入符号..?:
echo ^"^
needs this ^
to be quoted^
^"
-> "需要将此内容引用^"
虽然使用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"
written
on a
few lines
%}}%
在没有尖括号的情况下,命令更易读取,但是使用特殊符号例如括号、重定向等会破坏其结构。因此,在更简单的情况下,您可以这样做。不过,您仍然可以将参数用双引号括起来。
^
后面加上一个空格,你就可以在下一行开始而不需要空格。 - Joseph Daigleco^␍py ^␍file1 ^␍file2
。我建议您删除您的评论以避免混淆,尤其是因为这个问题非常受欢迎。 - Borodin