819

How can I split long commands over multiple lines in a batch file?

Ondra Žižka
  • 36,997
  • 35
  • 184
  • 250

6 Answers6

1030

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
Maximilian Burszley
  • 15,132
  • 3
  • 27
  • 49
Wayne
  • 34,159
  • 4
  • 36
  • 48
  • 107
    You can start the next line without a space if you add a space just before the `^` and after your command text. – Joseph Daigle Sep 16 '08 at 03:21
  • 2
    Seems to be limited to just the first two additional lines? – Seba Illingworth Jul 31 '10 at 02:47
  • Worked for me beautifully with a SQL script that executes long SQL queries using sqlcmd.exe . Delayed expansion even allows me to escape the greater-than and less-than chars. Thanks! – djangofan Nov 14 '11 at 19:54
  • 4
    @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 K Sep 18 '12 at 23:26
  • @Andriy M - I hear you. I don't believe there needs to be a space before or after the last carrot on a line if you are trying to do a line continuation. More specifically, I believe you have to do it one of two ways: 1) a space before the carrot and the next line need not have a space OR 2) no space before or after carrot but next line starts with a space. – djangofan Jun 10 '13 at 16:00
  • 18
    For safety **_always_ end with blank line** when using carets, see [Simple carat in batch file consumes all memory](http://stackoverflow.com/questions/15466298) – matt wilkie Oct 08 '13 at 20:19
  • The description of spaces around the caret in this answer is *really* confused. It's very simple: In the result, the caret and the newline that follows it don't exist. So if there was supposed to be a space there (as in between command parameters), you need to put a space there. I've rewritten this answer [here](http://stackoverflow.com/a/21000752/157247). I would normally just edit the answer, but it seemed wrong to *completely rewrite* someone else's answer. – T.J. Crowder Jan 08 '14 at 16:08
  • 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 – Borodin Aug 07 '15 at 21:49
  • @SebaIllingworth - I tried to use ^ to break my own long command to 7 lines and it worked just fine (windows 7). Below, there is an answer that states that there are limitation to the total length of broken command - maybe that was you chokepoint? You could make tests with short generic commands like 'type' to show few files like 1.txt 2.txt etc... – Jaiden Snow Apr 24 '16 at 08:39
  • 6
    One 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. – GregHNZ Aug 09 '17 at 02:39
  • 1
    Make sure not to put double quotes around your variable, it requires extra wizardry to make it work: https://stackoverflow.com/questions/4643376/how-to-split-double-quoted-line-into-multiple-lines-in-windows-batch-file – Noumenon May 13 '18 at 13:31
  • A special character `<>|"&^` at the beginning of a wrapped piece will lose its special meaning due to the continuation caret escaping it. So starting each wrapped piece with a space seems a safe habit. `the line continuation escapes the first character of the next line` --@dbenham, April 2012. – eel ghEEz Mar 06 '19 at 04:25
290

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).

Peter Mortensen
  • 28,342
  • 21
  • 95
  • 123
jeb
  • 70,992
  • 15
  • 159
  • 202
  • The final code block with the line feed example does not display the blank line, even though it is there. (At least it doesn't show up in IE7) Try reformatting using a blockquote instead. – dbenham Nov 22 '11 at 23:15
  • 6
    The 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? – jeb Nov 24 '11 at 12:02
  • 1
    i 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. – rjt Apr 05 '16 at 20:55
  • 1
    @jeb, wrote up an example failing cmd script, but then found this question: https://stackoverflow.com/questions/4643376/splitting-doublequoted-line-into-multiple-lines-in-windows-batch – rjt Apr 06 '16 at 12:46
  • 1
    This 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"`. – Alexander Gelbukh May 06 '20 at 23:26
  • @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 at `To suppress the escaping of the next character you can use a redirection. ...` – jeb Oct 07 '20 at 09:10
82

(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.)

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).

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.

Community
  • 1
  • 1
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
21

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 ^
Todd Partridge
  • 563
  • 6
  • 9
  • 1
    The line `cmd1.bat && cmd2.bat` is different from the parens form: execute `cmd2.bat` iff `cmd1.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. – Paul Michalik Jul 19 '18 at 09:45
  • `( echo hello )` results in an empty line. – basickarl Feb 13 '20 at 14:52
  • best and cleanest answer! carets are ugly and problematic in regex – neoscribe May 19 '20 at 00:06
9

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.

Mohammed Safwat
  • 141
  • 2
  • 7
  • Of 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. – Aacini Feb 11 '16 at 16:07
  • But what if `do` part contains multiple/nested `if-else` statements ? – Vicky Dev Dec 19 '16 at 19:59
  • Then you can simply use parentheses to enclose the statements like for %n in (hello bye) do ( echo %n echo %n ) – Mohammed Safwat Dec 27 '16 at 22:39
  • this a possible approach but you first need to store all the items in one line and execute it once. – npocmaka Nov 09 '20 at 12:56
3

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 this for more simpler cases. Though you can still enclose parameters in double quotes

npocmaka
  • 51,748
  • 17
  • 123
  • 166