As an example of the problem I'm seeing, the command
for /D %%i in (*) do @if not exist m:\home\%%i echo %%i
gives me a list of directories in the current directory that don't exist in the other directory.
However, if I want to pipe the output to another command, for example:
(for /D %%i in (*) do @if not exist m:\home\%%i echo %%i) | findstr /n .
I get this error message:
echo was unexpected at this time.
Note that I can't just leave the brackets out, because that would result in the pipe operator being processed once per iteration of the loop; I need the output of the loop piped to a single instance of an application. For example, if I leave the brackets out in this example, the line number from findstr
will always be shown as 1 rather than counting the number of directories.
Does anybody know how to make this work, preferably in the general case rather than just this specific example?
Windows 7 SP1 x64.
It's a problem of the parser with special IF
syntax forms like:
IF exist
IF defined
IF errorlevel
IF x EQU y
But this one works without problems
IF x == y
It can be solved with defining a variable containing a single IF
.
set "_IF_=IF"
( %%_IF_%% defined path echo It's defined ) | more
( %%_IF_%% errorlevel 0 echo Errorlevel is 0 or above ) | more
This works, as the %%_IF_%%
will be expanded not before the child process parses the block.
As per Eryksun's comments, this is definitely a bug. It can be worked around by explicitly creating a child process, rather than letting the batch processor do it for you:
cmd /s /c "for /D %%i in (*) do @if not exist m:\home\%%i echo %%i" | findstr /n .
Another option is to manually inject the missing space, by defining %space%
to be a single space and saying:
(for /D %%i in (*) do @if not exist ^%%space^%% m:\home\%%i echo %%i) | findstr /n .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With