2012-05-11 33 views

Odpowiedz

43

wygląd w następujących przykładach ...

Przykład 1: Następujący kod nie używa opóźnione ekspansji, tak więc zmienne w pętli są rozszerzone tylko jeden raz. Oznacza to, że %Count% zawsze będzie rozwijać się 0 w każdej iteracji pętli, bez względu na to, co zrobić, aby go z zestawu poleceń:

@echo off 
set COUNT=0 

for %%v in (1 2 3 4) do (
    set /A COUNT=%COUNT% + 1 
    echo Count = %COUNT% 
) 
pause 

Więc ten skrypt wyjściowe:

Count = 0 
Count = 0 
Count = 0 
Count = 0 

to jest nie w jaki sposób ta pętla ma działać.

Przykład 2: Z drugiej strony, jeśli używamy opóźnionego rozszerzenia, mamy następujący skrypt, który będzie działał zgodnie z oczekiwaniami.

setlocal ENABLEDELAYEDEXPANSION 
set COUNT=0 

for %%v in (1 2 3 4) do (
    set /A COUNT=!COUNT! + 1 
    echo Count = !COUNT! 
) 

pause 

i, zgodnie z oczekiwaniami, to wyświetli:

Count = 1 
Count = 2 
Count = 3 
Count = 4 

Podczas korzystania z ENABLEDELAYEDEXPANSION i poszerzyć zmienną używając ! zamiast %, zmienna zostanie ponownie rozszerzony za każdym razem, a wszystko działa tak, jak powinno.

+0

Dobrymi przykładami. Ale jeszcze lepiej byłoby użyć 'set/A COUNT = COUNT + 1' lub krótszego' set/A COUNT + = 1', aby zademonstrować, że w wyrażeniu __arithmetic__ można odwoływać się do zmiennych tylko ich nazwami. Wyrażenie __arithmetic__ jest ciągiem po 'set/A'. Wyjście pomocy działające w oknie wiersza poleceń 'set /?' Wyjaśnia opóźnione rozszerzenie w przykładzie __IF__ i __FOR__, a także specjalną zmienną parsującą w wyrażeniach arytmetycznych. – Mofi

7

Chciałem dodać świetny przykład na to, jak "EnableDelayedExpansion" (EDE) może być użyteczne poza wszechobecnymi przykładami pętli FOR.

o to linia danych sejsmicznej, że używa do analizowania (I połączyć It 1line.txt)

ak_11574812 2015.04.29.193822 62,9525 -148,8849 1,0 9,5 1 49km S z Cantwell Alaska

Wystąpił problem polegający na tym, że ostatni segment tej linii nie zawsze zaczyna się od tego samego numeru kolumny. Musiałem więc stworzyć elastyczne polecenie SET, które dokładnie zrzuci ostatni segment tej linii.

ECHO OFF 
setlocal enableDelayedExpansion 
set where=72 
set /p line=<1line.txt 
set locate=!line:~%where%,28! 
echo %locate% 

EDE pozwala mi umieścić zmienną (gdzie) wewnątrz innej zmiennej (linii). EDE przetłumaczy zmienną w nawiasie na%, a następnie przetworzy zmienną w nawiasie! i (w tym przypadku) wypchnij wyniki do zmiennej "zlokalizuj".

+0

Chociaż nie jest to bezpośrednio związane z pytaniem, to było jedyne miejsce, w którym udało mi się dowiedzieć, jak usunąć sub-łańcuchy, przekazując zmienne i jaka była prawidłowa kolejność! I%, więc dziękuję:) –

7

podaje przykład skryptu wsadowego, który działałby inaczej z lub bez opóźnionego rozszerzenia.

Dla kompletności, niech odpowie kolejną część pytania i pokazać sytuacji, w której byś nie chcą używać opóźnionego ekspansji gdy dane zawierają wykrzyknik ! (pokazywał dwa sposoby przetwarzania takich danych) :

@ECHO OFF 
SETLOCAL EnableExtensions DisableDelayedExpansion 

    set "_auxFile=%temp%\%~n0.txt" 
    rem create multiline sample file 
    >"%_auxFile%" (for /L %%G in (1,1,3) do echo line %%G is 100%% valid! Sure! Hurrah!) 
    rem create one-line sample file 
    >"%_auxFile%" echo this line is 100%% valid! Sure! Hurrah! 

    echo(
    echo --- file content 
    type "%_auxFile%" 

    echo(
    SETLOCAL EnableDelayedExpansion 
    echo --- enabled delayed expansion chokes down unescaped exclamation marks^^^! "^!" 
    for /F "usebackq delims=" %%G in ("%_auxFile%") do (
     set "_auxLine=%%~G" 
     echo loop var=%%~G 
     echo _auxLine=!_auxLine! 
    ) 
    ENDLOCAL 
    echo(
    SETLOCAL DisableDelayedExpansion 
    echo --- toggled delayed expansion works although might be laborious! 
    for /F "usebackq delims=" %%G in ("%_auxFile%") do (
     set "_auxLine=%%G" 
     echo loop var=%%G 
     SETLOCAL EnableDelayedExpansion 
     echo _auxLine=!_auxLine! 
     ENDLOCAL 
    ) 
    ENDLOCAL 
    echo(
    SETLOCAL DisableDelayedExpansion 
    echo --- keep delayed expansion DISABLED: use CALL command! 
    for /F "usebackq delims=" %%G in ("%_auxFile%") do (
     set "_auxLine=%%G" 
     echo loop var=%%G 
     call :ProcessVar 
    ) 
    ENDLOCAL 

    rem delete the sample file 
    del "%_auxFile%" 
ENDLOCAL 
goto :eof 

:ProcessVar 
    echo _auxLine=%_auxLine% 
    echo WARNING: neither !_auxLine! nor %%G loop variable is available here! 
goto :eof 

Zauważ, że powyższy scenariusz pokazuje proper ways of escaping

  • % znak procent przez %% podwojenie (opóźnione expansi nie ma znaczenia), a znak
  • ! wykrzyknik czy opóźniony rozbudowa jest włączona:
    • "^!" jeśli zamknięty w cudzysłowy, a następnie użyć ogólnego charakteru uciec cmd i partia-Script ^ daszka;
    • ^^^! w przeciwnym razie użyj trzech kostek ^.

Wyjście:

==> D:\bat\SO\10558316.bat 

--- file content 
this line is 100% valid! Sure! Hurrah! 

--- enabled delayed expansion chokes down unescaped exclamation marks! "!" 
loop var=this line is 100% valid Hurrah 
_auxLine=this line is 100% valid Hurrah 

--- toggled delayed expansion works although might be laborious! 
loop var=this line is 100% valid! Sure! Hurrah! 
_auxLine=this line is 100% valid! Sure! Hurrah! 

--- keep delayed expansion DISABLED: use CALL command! 
loop var=this line is 100% valid! Sure! Hurrah! 
_auxLine=this line is 100% valid! Sure! Hurrah! 
WARNING: !_auxLine! as well as %G loop variables are not available here! 

==> 
+0

+1 tylko dla tej środkowej sekcji i łącza; Szukałem tych informacji odkąd wyszedłem z łona. – Andrew

Powiązane problemy