[HOWTO] les variables ForInDo
salut,
Dans ce petit HOWTO, j'essayerais d'expliquer une notion importante de la boucle ForInDo: les variables ForInDo
1) la logique du réferencement des variables:
dans une boucle forindo, les variables ne sont pas limités seulement à un intervalle de %%a à %%z et de %%A à %%Z
Code:
1 2 3
| CMD:\> type f1.bat
for /f "useback tokens=1-3" %%Z in ('1 2 3') do echo %%[ - %%\ |
Explication:
la raison de ce comportement est que ces types de variables sont conçus pour "tokenizer/découper" des expressions qui peuvent être très longues, ainsi on aurra besoin d'une suite logique qui nous permettera d'indexer nos "tokens" et de traiter le plus grand nombre possible de 'tokens' d'une expression....la suite logique dans notre cas sera la suite des caractères ASCII.
2) sensibilité à la case
contrairement aux autres types de variables, les variables dans les boucles Forindo sont sensibles à la case
Exemple
Code:
1 2 3 4
| CMD:\> Type f2.bat
for %%a in (1) do echo %%A
for %%a in (2) do echo %%a |
Explication
dans l'encodage ASCII la lettre "A" correspond à (x041) et la lettre "a" correspond à (x061)
en interne la boucle forindo fait une comparaison entre la variable d'entrée (x041) et la variable de sortie (x061) avant d'afficher leurs contenu...dans notre cas les deux caractères sont différents.
3) portée des variables (scope)
on ne peux pas les utiliser en dehors des boucles forindo, et ils ne sont pas visibles dans le corps de la boucle forindo parente
Exemple1:
Code:
1 2 3 4
| CMD:\> type f3.bat
for %%a in ("%__CD__%") do echo %%~a
echo %%~a |
Code:
1 2 3 4 5
|
CMD:\> f3.bat
D:\Documents and Settings\
%~a |
Exemple2:
Code:
1 2 3 4 5 6
| CMD:\> type f3.bat
for %%a in (1) do (
for %%b in (2) do echo 2 %%a - %%b
echo 1 %%a - %%b
) |
Code:
1 2 3 4
| CMD:\> a3.bat
2 1 - 2
1 1 - %b |
Explication:
ces types de variables sont générer par la boucle forindo "local", c'est la raison pour laquelle ils sont visible seulement dans la portée local et enfant.
Code:
1 2 3 4 5 6 7 8 9 10
| CMD:\> type f3_exp.bat
for %%a in (1) do (
for %%b in (2) do (
for %%c in (3) do (
echo %%a - %%b - %%c
)
)
) |
Code:
1 2 3 4
|
CMD:\> f3_exp.bat
1 - 2 - 3 |
4) extraction et substitution de variables
les variables forindo ne supportent ni les substitutions ni le paramètrage:
Exemple:
Code:
1 2 3
| CMD:\> type f4.bat
for %%a in ("hello") do echo %%~a:~0,3% |
Code:
1 2 3 4
|
CMD:\> f4.bat
hello:~0,3 |
Explication:
chaque variable forindo est en mode 'Read-Only'. elle ne peut être changer ni dans la boucle forindo ni en dehors de celle-ci
5) modificateurs de variables
les variables forindo peuvent être modifier par des modificateurs spéciales: (pour plus de détails voir: "help for")
Exemple:
Code:
1 2 3 4
|
CMD:\> type f5.bat
for %%a in (*) do echo %%~asa |
Code:
1 2 3 4 5
| CMD:\> f5.bat
--a------ D:\DOCUME~1\Bureau\f1
--a------ D:\DOCUME~1\Bureau\f2
--a------ D:\DOCUME~1\Bureau\f3 |
Explication:
ces modificateurs sont prédéfinis et sont conçus généralement pour le traitement avec le system de fichiers.
Notes:
parfois ces modificateurs peuvent provoquer des bugs: (en raison du nombres de ces bugs, on prendra qu'un seul cas)
Code:
1 2 3 4 5 6 7 8 9 10 11
| CMD:\> REM verification de l'existance des fichiers de test
CMD:\> dir c:\*.htm /b
12.htm
bookmarks.htm
CMD:\> type note.bat
for /f "tokens=*" %%a in ('dir *.bat /b') do echo %%~tnxa
echo ******************
for /f "tokens=*" %%a in ('dir c:\*.htm /b') do echo %%~tnxa |
Code:
1 2 3 4 5 6 7
| CMD:\> note.bat
09/05/2011 09:32 2.bat
09/05/2011 10:48 3.bat
**************
12.htm
bookmarks.html |
Explication:
par defaut, le modificateur de date (~t) est disponible seulement dans le répertoire en cours.
6) partage de variables en interne et en externe
il est possible de partager des variables forindo dans un même script ou dans des scripts externes. Il faut prendre en compte aussi que ce partage ne se fait que dans un seul sens...c'est à dire de l'appelant à l'appelé et non pas de l'appelé à l'appelant
(A) partage en interne:
Code:
1 2 3 4 5 6 7 8 9 10 11
| CMD:\> type f6.bat
@echo off
for %%a in (X) do (
call :label
)
pause
exit
:label
for /l %%p in (1 1 3) do echo %%a - %%p |
Code:
1 2 3 4 5
| CMD:\> f6.bat
X - 1
X - 2
X - 3 |
Explication:
la commande CALL va permettre à la boucle forindo de créer en interne une copie de la variable.
en cas de conflit entre les noms de variables, la variable de la boucle local prendra le dessus:
Exemple:
(A) Exemple partage en interne
Code:
1 2 3 4 5 6 7 8 9 10 11 12
|
CMD:\> type f7.bat
@echo off
for %%a in (X) do (
call :label
)
pause
exit
:label
for /l %%a in (1 1 3) do echo %%a - %%a |
Code:
1 2 3 4 5
| CMD:\> f7.bat
1 - 1
2 - 2
3 - 3 |
(B) Exemple partage en externe
On va créer trois fichiers de commandes 1.bat, 2.bat et 3.bat et on essayera de partager des variables forindo entre ces différents scripts
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| CMD:\> REM On affiche le contenu des trois scripts externes
CMD:\> type *.bat
1.bat
---------
@echo off
for %%a in (1) do (call 2.bat
echo %~nx0
echo %%a %%b %%c
)
pause
2.bat
--------
echo %0
for %%b in (2) do (echo %%a - %%b - %%c
echo.
call 3.bat
)
3.bat
--------
echo %0
for %%c in (3) do (echo %%a - %%b - %%c
echo.
) |
Code:
1 2 3 4 5 6 7 8 9 10 11
|
CMD:\> 1.bat
2.bat
1 - 2 - %c
3.bat
1 - 2 - 3
1.bat
1 %b %c |
7) comparaison entre les variables forindo et les variables "traditionnels":
par defaut, les variables forindo supportent mieux les caractères reservés que les variables "traditionnelles"
Code:
1 2 3 4 5 6 7
| CMD:\> type f8.bat
for %%e in ("(<|>&)") do (
echo %%~e
set e=%%~e
echo %e%
) |
Code:
1 2 3 4
| CMD:\> f8.bat
(<|>&)
Commande ECHO désactivée. |
Explication
on peux utiliser les variables forindo directement, sans avoir besoin d'assignation, ceci va nous permettre d'executer la variable avant d'interpréter son contenu.
8) expansion de variables:
les variables forindo permettent un réferencement textuel simple:
Exemple
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| CMD:\> type f9.bat
@echo off
setlocal enabledelayedexpansion
set a=b
set c=a
for %%a in (%c%) do echo %%a
for %%a in (%c%) do echo !%%a!
pause |
Explication
cette technique est comparable aux 'expansions simples' des variables traditionnels