Quelqu'un peut-il me donner un exemple où un script batch agirait différemment avec ou sans expansion retardée? Y a-t-il des situations où vous ne voudriez PAS utiliser l'expansion retardée? Merci.
Regardez les exemples suivants ...
Exemple 1: Le code suivant N'UTILISE PAS l'expansion retardée, donc les variables de la boucle for ne sont développées qu'une seule fois. Cela signifie que %Count%
sera toujours étendu à 0
à chaque itération de la boucle, peu importe ce que nous lui faisons avec la commande set:
@echo off
set COUNT=0
for %%v in (1 2 3 4) do (
set /A COUNT=%COUNT% + 1
echo Count = %COUNT%
)
pause
Donc, ce script affichera:
Count = 0
Count = 0
Count = 0
Count = 0
Ce n'est pas ainsi que cette boucle est censée fonctionner.
Exemple 2: D'autre part, si nous utilisons une expansion retardée, nous avons le script suivant, qui s'exécutera comme prévu.
setlocal ENABLEDELAYEDEXPANSION
set COUNT=0
for %%v in (1 2 3 4) do (
set /A COUNT=!COUNT! + 1
echo Count = !COUNT!
)
pause
et, comme prévu, il affichera:
Count = 1
Count = 2
Count = 3
Count = 4
Lorsque vous utilisez ENABLEDELAYEDEXPANSION
et développez une variable à l'aide de !
au lieu de %
, la variable est re-développée à chaque fois, et tout fonctionne comme prévu.
Je voulais ajouter un excellent exemple sur la façon dont "EnableDelayedExpansion" (EDE) peut être utile en dehors des exemples de boucle FOR omniprésents.
Voici une ligne de données sismiques que je souhaite analyser (je l'appelle 1line.txt)
ak_11574812 2015.04.29.193822 62.9525 -148.8849 1.0 9.5 1 49 km S de Cantwell, Alaska
Le problème que j'ai rencontré était que le dernier segment de cette ligne ne démarre pas toujours au même numéro de colonne. J'ai donc dû créer une commande SET flexible qui arrachera avec précision le dernier segment de cette ligne.
ECHO OFF
setlocal enableDelayedExpansion
set where=72
set /p line=<1line.txt
set locate=!line:~%where%,28!
echo %locate%
EDE me permet de placer une variable (où) à l'intérieur d'une autre variable (ligne). EDE traduira d'abord la variable entre crochets par%, puis traitera la variable entre crochets par! et (dans ce cas) Poussez les résultats dans la variable "Locate".
réponse de Max donne un exemple de cas où un script batch agirait différemment avec ou sans expansion retardée.
Par souci d'exhaustivité, répondons à une autre partie de la question et montrons une situation où vous ne voudriez PAS utiliser l'expansion retardée lorsque vos données contiennent une exclamation marque !
(et montrer deux façons de traiter ces données):
@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
Notez que le script ci-dessus montre les bonnes façons de s'échapper
%
signe pour cent par %%
le doubler (l'expansion retardée n'a pas d'importance), et!
point d'exclamation si l'expansion différée est activée: "^!"
s'il est placé entre deux guillemets doubles, utilisez le cmd
et le caractère d'échappement général du script batch ^
caret;^^^!
sinon, utilisez trois ^
carets.Sortie :
==> 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!
==>