How to avoid percentage (%) when using parameters in a FOR loop?

The regular escape character in dos batch files is ^ . However, for percent, % , the delimiter for variables, the escape should double the percent: %%cd%% . Things change when using parameter extensions inside a for loop. Instead of %%~dpnx0 emitting %~dpnx0 , since it goes beyond the loop, it performs a replacement emitting D:\Scripts\foo.py

Here's a demo of a batch file:

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

Here 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 tried to double, triple and quadruple the percentage, as well as navigate through all, all without success.

+7
source share
2 answers

Cannot expand variable expression for FOR variable. If FOR acts with the variable X, then the extension phase of FOR will always expand with %X

But you can hide the interest behind another FOR variable :)

Below is 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 a global scope (although they are only available in the DO clause). This can lead to an insidious problem. Every time you have a routine that uses a percent literal in a FOR loop, you run the risk of unexpected results! A FOR statement issued before your CALL may affect the results of a FOR DO clause in your CALLed procedure.

 @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 conclusion

 This works outside loop (confidence = 100%) This does not work inside loop (confidence = 100Yikes This works inside loop (confidence = 100%) 
+7
source

You can use the slow extension or call-percent extension, or, as dbenham shows, the extension of 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 ) 
+2
source

All Articles