The usual escape character in dos batch files is caret, ^
. However for percent, %
, the delimiter for variables, the escape is to double up the percents: %%cd%%
. Things change when using parameter extensions inside a for
loop. Instead of %%~dpnx0
emitting %~dpnx0
, as it will outside the loop, it carries out the substitution, emitting D:\Scripts\foo.py
.
Here's a batch file demonstration:
@echo off
echo This is a pipe: ^|
echo Use this var for the current directory: %%cd%%
echo Use this to echo full path of running batch file: %%~dpnx0
for %%a in (foo.py baz.py) do (
echo @python %%~dpnxa ^> %%~na.bat
)
These are the results I get:
This is a pipe: |
Use this var for the current directory: %cd%
Use this to echo full path of running batch file: %~dpnx0
@python d:\Scripts\foo.py > foo.bat
@python d:\Scripts\baz.py > baz.bat
But this is what I want:
This is a pipe: |
Use this var for the current directory: %cd%
Use this to echo full path of running batch file: %~dpnx0
@python %~dpnxa > foo.bat
@python %~dpnxa > baz.bat
I've tried doubling, tripling, and quadrupling the percents as well is interspersing carets throughout, all without success.
It is impossible to prevent a FOR variable expression from expanding. If a FOR is in effect with variable X defined, then the FOR expansion phase will always expand %X
.
But you can hide the percent behind another FOR variable :)
The following gives the result you are looking for:
@echo off
echo This is a pipe: ^|
echo Use this var for the current directory: %%cd%%
echo Use this to echo full path of running batch file: %%~dpnx0
for %%P in (%%) do for %%A in (foo.py baz.py) do (
echo @python %%P~dpnxA ^> %%~nA.bat
)
FOR variables have global scope (though they are only accessible within the DO clause). This can lead to an insidious problem. Any time you have a subroutine that uses a percent literal within a FOR loop, then you are at risk of unintended results! A FOR statement issued before your CALL can influence the results of a FOR DO clause within your CALLed routine.
@echo off
for %%) in (Yikes!) do call :test
exit /b
:test
echo This works outside loop (confidence = 100%%)
for %%A in (1) do echo This does not work inside loop (confidence = 100%%)
for %%P in (%%) do for %%A in (1) do echo This works inside loop (confidence = 100%%P)
exit /b
Here is the output
This works outside loop (confidence = 100%)
This does not work inside loop (confidence = 100Yikes
This works inside loop (confidence = 100%)
You could use delayed expansion or call-percent expansion, or like dbenham shows expanding another FOR variable.
setlocal EnableDelayedExpansion
set percent=%%
set "line=%%~dpnxa ^>"
for %%a in (foo.py baz.py) do (
echo @python !percent!~dpnxa ^> %%~na.bat
call echo @python %%line%% %%~nxa.bat
)
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