This snippet of code
forfiles /P %pathname% /M *.log /c "cmd /c echo @file"
will happily list out a bunch of files.
We could replace the ECHO
with RENAME
or MOVE
or many other combinations of internal commands: the exception being a CALL
to a label name.
For instance replacing the ECHO
above as follows:
forfiles /P %pathname% /M *.log /c "cmd /c CALL :listit @file"
: :
: :
exit /b
:listit
echo %1
exit /b
Which I would have hoped would have the same output gives an error message, typically
Invalid attempt to call batch label outside of batch script.
This behaviour is not something that Microsoft's documentation remarks on, and since the alternatives are perfectly adequate, I've not gone looking to make it work.
But I am interested in the Well, why not?!, and so I'm posing the Question
Why can't we use a CALL :label command in the FORFILES script?
Thank you.
As @Stephan commented already, it can't uses labels, because it's executed in a command line context.
In most of the cases you can use the simpler FOR
command.
But in cases where you need forfiles
and labels, this can be solved with a simple trick.
FOR /F ... goto :%%L
. forfiles ... call %~d0\:<myLabel>:\..\%~pn0
@echo off
FOR /F "tokens=3 delims=:" %%L in ("%~0") DO goto :%%L
...
forfiles /P %pathname% /M *.log /c "cmd /c CALL %~d0\:listit:\..\%~pn0 @file"
...
:listit
echo %1
exit /b
A good advice from aschipfl:
To add some more stability (against spaces in the path/filename) you can enclose the call destination into quotes call 0x22%~d0\:listit:\..\%~pn00x22 @file
.
This is a special syntax only in forfiles
, where 0xHH
is the hexadecimal code for the character 0x22="
.