145

Is it possible in Windows batch file to call more than one command in a single FOR loop? Let's say for example I want to print the file name and after delete it:

@ECHO OFF
FOR /r %%X IN (*.txt) DO (ECHO %%X DEL %%X)
REM the line above is invalid syntax.

I know in this case I could solve it by doing two distinct FOR loops: one for showing the name and one for deleting the file, but is it possible to do it in one loop only?

Ross Ridge
  • 38,414
  • 7
  • 81
  • 112
Marco Demaio
  • 33,578
  • 33
  • 128
  • 159

3 Answers3

230

Using & is fine for short commands, but that single line can get very long very quick. When that happens, switch to multi-line syntax.

FOR /r %%X IN (*.txt) DO (
    ECHO %%X
    DEL %%X
)

Placement of ( and ) matters. The round brackets after DO must be placed on the same line, otherwise the batch file will be incorrect.

See if /?|find /V "" for details.

Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315
Anders
  • 97,548
  • 12
  • 110
  • 164
  • 14
    This solution looks clean and readable. I would also warn any programmer who uses this solution that the round bracket after the `DO` must NOT be placed next line otherwise it brakes the batch file. In code when I write a for loop I commonly place the curly bracket `{` next line. – Marco Demaio Feb 10 '11 at 10:49
  • 2
    Also -- be wary if any of your nested commands have brackets in (for example, something like "echo Something something (something else)" EDIT: ah, see bk1e's answer :) – Tim Barrass Oct 29 '15 at 16:06
  • The key is: The round brackets after DO must be placed on the same line, otherwise the batch file will be incorrect! – terwxqian Jan 19 '21 at 06:21
132
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)
Steven
  • 1,365
  • 2
  • 13
  • 28
Kalle
  • 2,282
  • 1
  • 24
  • 30
  • 2
    Actually, I think the parentheses are unnecessary. `for %i in (1 2 3) do echo %i & echo foo` prints what I'd expect: "1", "foo", "2", "foo", "3", "foo" (on separate lines). – bk1e Feb 13 '10 at 18:58
  • Shouldn't that be `&&` rather than `&`? – jww Oct 17 '15 at 01:31
  • 12
    @jww `&&` will fail if the first command fails, `&` will execute the second command regardless. – yyny Mar 14 '16 at 21:27
  • If this solution makes a syntax error for you, check out if you got an unescaped paren between the `DO`-parens. You may escape them by appending a `^` to them. – Константин Ван Jul 28 '18 at 14:26
36

SilverSkin and Anders are both correct. You can use parentheses to execute multiple commands. However, you have to make sure that the commands themselves (and their parameters) do not contain parentheses. cmd greedily searches for the first closing parenthesis, instead of handling nested sets of parentheses gracefully. This may cause the rest of the command line to fail to parse, or it may cause some of the parentheses to get passed to the commands (e.g. DEL myfile.txt)).

A workaround for this is to split the body of the loop into a separate function. Note that you probably need to jump around the function body to avoid "falling through" into it.

FOR /r %%X IN (*.txt) DO CALL :loopbody %%X
REM Don't "fall through" to :loopbody.
GOTO :EOF

:loopbody
ECHO %1
DEL %1
GOTO :EOF
bk1e
  • 23,871
  • 6
  • 54
  • 65
  • 3
    While we are on the topic, %X is never correct when dealing with filenames, always use "%~X" (In your example here, you could get away with using %* in the subfunction probably) – Anders Feb 13 '10 at 20:35
  • 1
    That's a really good point. A good example of a path that demonstrates both problems is `C:\Program Files (x86)`. – bk1e Feb 13 '10 at 20:55