2012-12-04 2 views
7

Zwykły znak escape w plikach wsadowych DOS to caret, ^. Jednak dla procentu, %, ogranicznik dla zmiennych, ucieczka polega na podwojeniu procentów: %%cd%%. Rzeczy zmieniają się, gdy używasz pętli parameter extensions wewnątrz pętli . Zamiast %%~dpnx0 emitowania %~dpnx0, jak to będzie poza pętli, wykonuje substytucję, emitując D:\Scripts\foo.py.Jak uniknąć procentu (%) podczas używania parametrów w pętli FOR?

Oto demonstracja plik wsadowy:

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

Są to wyniki uzyskać:

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 

Ale to, co chcę:

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 

Próbowałem podwojenie Potrojenie i czterokrotne powiększenie procentów to także interspersing carets - wszystko bez powodzenia.

Odpowiedz

7

Nie można zapobiec rozszerzaniu wyrażenia zmiennej FOR. Jeśli FOR działa w przypadku zdefiniowanej zmiennej X, faza ekspansji FOR zawsze będzie się rozszerzać o %X.

Ale można ukryć procent za sobą o zmiennej :)

Poniżej przedstawiono wynik szukasz:

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

dla zmiennych mają zasięg globalny (choć są one dostępne jedynie w ramach Klauzula DO). Może to prowadzić do podstępnego problemu. Za każdym razem, gdy masz podprogram, który używa literału procentowego w pętli FOR, możesz ryzykować niezamierzone rezultaty! Oświadczenie FOR wydane przed Twoim CALL może mieć wpływ na wyniki klauzuli FOR DO w ramach procedury CALLed.

@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 

Oto wynik

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

whoa, to dziwne, ale działa, +1. Dzięki! (opóźniając przyjęcie, aby sprawdzić, czy pojawią się jakieś inne rozwiązania) –

+2

@mattwilkie - dodałem kolejny przykład pokazujący, jak podstępny może być problem! – dbenham

2

Można użyć opóźnione ekspansji lub zadzwoń procent ekspansji, lub jak dbenham pokazuje rozszerzenie innego dla zmiennej.

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 
)