2012-05-11 5 views

Antwort

43

Blick auf die folgenden Beispiele ...

Beispiel 1: Der folgende Code NICHT verzögert Expansion verwenden, so dass die Variablen in der for-Schleife werden nur einmal erweitert. Das bedeutet, dass %Count% wird immer auf 0 in jeder Iteration der Schleife erweitern, egal, was wir mit dem Set-Befehl, es zu tun:

@echo off 
set COUNT=0 

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

Also das Skript ausgegeben:

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

Dies ist nicht wie diese Schleife funktionieren soll.

Beispiel 2: Auf der anderen Seite, wenn wir verzögerte Expansion verwenden, haben wir das folgende Skript, das wie erwartet ausgeführt wird. eine Variable ! statt % wird die Variable jedes Mal erneut erweitert, und alles

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

Wenn Sie die ENABLEDELAYEDEXPANSION verwenden und erweitern:

setlocal ENABLEDELAYEDEXPANSION 
set COUNT=0 

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

pause 

und, wie erwartet, wird es ausgegeben funktioniert so, wie es soll.

+0

Gute Beispiele. Aber noch besser wäre 'set/A COUNT = COUNT + 1' oder kürzer' set/A COUNT + = 1', um zu demonstrieren, dass innerhalb eines __arithmetischen Ausdrucks__ Variablen nur mit ihren Namen referenziert werden können. Ein __arithmetischer Ausdruck__ ist die Zeichenfolge nach 'set/A'. Die Hilfeausgabe beim Ausführen in einem Eingabeaufforderungsfenster 'set /?' Erklärt die verzögerte Erweiterung bei einem __IF__- und einem __FOR__-Beispiel und auch bei der Analyse spezieller Variablen in arithmetischen Ausdrücken. – Mofi

7

Ich wollte ein großartiges Beispiel hinzufügen, wie "EnableDelayedExpansion" (EDE) außerhalb der allgegenwärtigen FOR-Schleife-Beispiele nützlich sein kann.

ist hier eine Reihe von Erdbebendaten, die wir analysieren wollen (ich nenne es 1line.txt)

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

Das Problem, auf das ich stieß, war, dass das letzte Segment dieser Zeile nicht immer bei der gleichen Spaltennummer beginnt. Also musste ich einen flexiblen SET-Befehl erstellen, der das letzte Segment dieser Linie genau ausreißt.

EDE ermöglicht mir, eine Variable (wo) in eine andere Variable (Zeile) zu platzieren. EDE übersetzt zuerst die Variable, die von% eingeklammert wird, und verarbeitet dann die Variable, die von! und (in diesem Fall) schiebe die Ergebnisse in die Variable "locate".

+0

Obwohl ich nicht direkt mit der Frage in Verbindung stand, war dies der einzige Ort, an dem ich herausfinden konnte, wie man Sub-Strings durch Übergabe von Variablen löscht, und was die richtige Reihenfolge von! 'S und%' s war, also danke:) –

7

Max's answer gibt ein Beispiel dafür, wo ein Batch-Skript mit oder ohne verzögerte Erweiterung anders reagieren würde.

Aus Gründen der Vollständigkeit, lassen Sie uns einen anderen Teil der Frage beantworten und eine Situation zeigen, wo Sie würde nicht wollen, verzögerte Expansion verwenden, wenn Sie Ihre Daten ein Ausrufezeichen enthalten ! (und zeigen zwei Möglichkeiten solcher Datenverarbeitung) :

@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 

Beachten sie, dass obige Skript zeigt proper ways of escaping

  • % Prozentzeichen durch %% es verdoppelt (verzögert ERWEITE auf spielt keine Rolle) und
  • ! Ausrufezeichen, wenn verzögerte Erweiterung aktiviert ist:
    • "^!" wenn in einem Paar von doppelten Anführungszeichen, dann verwenden, um das cmd und Batch-Skript allgemeinen Escape-Zeichen ^ caret;
    • ^^^! Ansonsten verwenden Sie drei ^ Carets.

Ausgang:

==> 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 nur für diesen mittleren Abschnitt und den Link; Seit ich aus dem Mutterleib gekommen bin, habe ich nach diesen Informationen gesucht. – Andrew

Verwandte Themen