How can I split long commands over multiple lines in a batch file?
7 Answers
You can break up long lines with the caret ^
as long as you remember that the caret and the newline following it are completely removed. So, if there should be a space where you're breaking the line, include a space. (More on that below.)
Example:
copy file1.txt file2.txt
would be written as:
copy file1.txt^ file2.txt
- 145You can start the next line without a space if you add a space just before the
^
and after your command text.CommentedSep 16, 2008 at 3:21 - 5@SebaIllingworth - No, you can always add [SPACE]+[^] and two blank lines to create a total of 2 line-feeds when it's
echo
ed.– James KCommentedSep 18, 2012 at 23:26 - 37For safety always end with blank line when using carets, see Simple carat in batch file consumes all memoryCommentedOct 8, 2013 at 20:19
- 4@GavinMiller: "caret ^ after copy and file1.txt on a new line won't work" That isn't true. You can split the line anywhere, including in the middle of a word, like
co^␍py ^␍file1 ^␍file2
. I suggest you delete your comment to avoid confusion, especially as this questyion is such a popular one– BorodinCommentedAug 7, 2015 at 21:49 - 13One gotcha here is that the ^ has to be the last character on the line - i.e. no spaces after. I was having trouble with this and it turned out I had a bunch of spaces after the caret - not easily visible in the editor I was using.– GregHNZCommentedAug 9, 2017 at 2:39
The rule for the caret is:
A caret at the line end, appends the next line, the first character of the appended line will be escaped.
You can use the caret multiple times, but the complete line must not exceed the maximum line length of ~8192 characters (Windows XP, Windows Vista, and 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
To suppress the escaping of the next character you can use a redirection.
The redirection has to be just before the caret. But there exist one curiosity with redirection before the caret.
If you place a token at the caret the token is removed.
echo Test5 echo one <nul ^ & echo two --- Output --- Test5 one two echo Test6 echo one <nul ThisTokenIsLost^ & echo two --- Output --- Test6 one two
And it is also possible to embed line feeds into the string:
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
The empty line is important for the success. This works only with delayed expansion, else the rest of the line is ignored after the line feed.
It works, because the caret at the line end ignores the next line feed and escapes the next character, even if the next character is also a line feed (carriage returns are always ignored in this phase).
- 6The question is, do we should support a bad tool that didn't follow the rules (someone call it a browser, but it isn't) or do you should switch to a browser?– jebCommentedNov 24, 2011 at 12:02
- 2i had double quotes surrounding my values, as in set var="text here ^ " but it does not work. Remove the double quote and it is fine.– rjtCommentedApr 5, 2016 at 20:55
- 1@jeb, wrote up an example failing cmd script, but then found this question: stackoverflow.com/questions/4643376/…– rjtCommentedApr 6, 2016 at 12:46
- 3This does not work if the next line starts with a quotation mark:
copy ^[newline]"file1.txt" ^[newline]"file2.txt"
does not work! I had to add a space:copy ^[newline] "file1.txt" ^[newline] "file2.txt"
.CommentedMay 6, 2020 at 23:26 - 2@AlexanderGelbukh That's the expected behaviour, described
...the first character of the appended line will be escaped.
you can use a space or the solution described atTo suppress the escaping of the next character you can use a redirection. ...
– jebCommentedOct 7, 2020 at 9:10
You can break up long lines with the caret (^
), just remember that the caret and the newline that follows it are removed entirely from the command, so if you put it where a space would be required (such as between parameters), be sure to include the space as well (either before the ^
, or at the beginning of the next line — that latter choice may help make it clearer it's a continuation).
⚠ Note: The first character of the next line is escaped. So if it carries any special meaning (like &
or |
), that meaning will be lost and it will be interpreted as a pure text character (see last example at bottom).
Examples: (all tested on Windows XP and Windows 7)
xcopy file1.txt file2.txt
can be written as:
xcopy^ file1.txt^ file2.txt
or
xcopy ^ file1.txt ^ file2.txt
or even
xc^ opy ^ file1.txt ^ file2.txt
(That last works because there are no spaces betwen the xc
and the ^
, and no spaces at the beginning of the next line. So when you remove the ^
and the newline, you get...xcopy
.)
For readability and sanity, it's probably best breaking only between parameters (be sure to include the space).
Be sure that the ^
is not the last thing in a batch file, as there appears to be a major issue with that.
Here's an example of character escaped at the start of the next line:
xcopy file1.txt file2.txt ^ & echo copied successfully
This will not work because &
will be escaped and lose its special meaning, thus sending all of "file1.txt file2.txt & echo copied successfully" as parameters to xcopy
, causing an error (in this example).
To circumvent, add a space at the beginning of the next line.
(This is basically a rewrite of Wayne's answer but with the confusion around the caret cleared up. So I've posted it as a CW. I'm not shy about editing answers, but completely rewriting them seems inappropriate.)
Multiple commands can be put in parenthesis and spread over numerous lines; so something like echo hi && echo hello
can be put like this:
( echo hi echo hello )
Also variables can help:
set AFILEPATH="C:\SOME\LONG\PATH\TO\A\FILE" if exist %AFILEPATH% ( start "" /b %AFILEPATH% -option C:\PATH\TO\SETTING... ) else ( ...
Also I noticed with carets (^
) that the if
conditionals liked them to follow only if a space was present:
if exist ^
- 1The line
cmd1.bat && cmd2.bat
is different from the parens form: executecmd2.bat
iffcmd1.bat
executed successfully (-without setting%errorcode%
). The latter form executes unconditionally. Somewhat unexpected (at least for me) is that, obviously, you can't use the combination of both + i.e. add&&
before the line break.CommentedJul 19, 2018 at 9:45 ( echo <line break here> hello )
results in an empty line.CommentedFeb 13, 2020 at 14:52- best and cleanest answer! carets are ugly and problematic in regexCommentedMay 19, 2020 at 0:06
It seems however that splitting in the middle of the values of a for loop doesn't need a caret(and actually trying to use one will be considered a syntax error). For example,
for %n in (hello bye) do echo %n
Note that no space is even needed after hello or before bye.
- 1Of course, this is part of the
for
syntax: the separators of elements in the "for-set" are space, comma, semicolon, equal-sign, TAB character and new-lines.– AaciniCommentedFeb 11, 2016 at 16:07 - But what if
do
part contains multiple/nestedif-else
statements ?CommentedDec 19, 2016 at 19:59 - Then you can simply use parentheses to enclose the statements like for %n in (hello bye) do ( echo %n echo %n )CommentedDec 27, 2016 at 22:39
- this a possible approach but you first need to store all the items in one line and execute it once.– npocmakaCommentedNov 9, 2020 at 12:56
One thing I did not find when searching for 'how to split a long DOS batch file line' was how to split something containing long quoted text. In fact it IS covered in the answers above, but is not obvious. Use Caret to escape them. e.g.
myprog "needs this to be quoted"
can be written as:
myprog ^"needs this ^ to be quoted^"
but beware of starting a line with Caret after ending a line with caret - because it will come out as caret..?:
echo ^"^ needs this ^ to be quoted^ ^"
-> "needs this to be quoted^"
- 1You don't need to escape the last quote. A caret (or any other special character) at the first column in a new line will be escaped by a multi line caret– jebCommentedJul 21, 2021 at 13:55
- good point! :) ... I'm using this for splitting VERY long ffmpeg '-vf' arguments, and it's working a treat.– Simon HCommentedJul 22, 2021 at 14:18
- what if the multiline needs to be quoted, eg ^"^ ....Get-Volume | Flush-Volume?– Al RoCommentedDec 30, 2023 at 19:56
Though the carret will be preferable way to do this here's one more approach using macro that constructs a command by the passed arguments:
@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 %}}%
command is easier to read without the carets but using special symbols e.g. brackets,redirection and so on will break it. So you can use this for more simpler cases. Though you can still enclose parameters in double quotes
- 5this is what black magic or Jamaican voodoo looks like.CommentedJan 7, 2022 at 13:59
- Regarding this previous comment "good point! :) ... I'm using this for splitting VERY long ffmpeg '-vf' arguments, and it's working a treat. – Simon H" Could you or someone please post a complete example of how you split a -vf filter to multiple lines" I have tried every example shown here in a variety of combinations and versions and I can't find the solution that will work in a quoted video filter command. Thanks. CommentedJul 22, 2021 at 14:18 "CommentedJul 21, 2024 at 14:38