salut,
ceci n'est pas une introduction sur la notion des variables..
ce petit topic peut être ajouter aux HOWTO précédents variables1/2
SET
1/ Assignation par référence
le scripting de command NT ne supporte pas nativement le référencement de variables, on peux contourner ce problème en utilisant une petite astuce qui s'appuie sur le comportement de l'interpreteur vis à vis de l'expansion des variables.
cette assignation par référence signifie que les deux variables pointent vers le même conteneur de donnée.
Les références sont un moyen d'accéder au contenu d'une même variable en utilisant plusieurs noms. Les références ne sont pas comme des pointeurs en C, vous ne pouvez pas effectuer d'opération arithmétique sur celles-ci.
1/a/ comment créer une réference:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
@echo off
setlocal DisableDelayedExpansion
set a=3
set b=!a!
setlocal EnableDelayedExpansion
echo %a% % affiche 3 %
echo %b% % affiche 3 %
set a=4 % change la variable a %
echo %a% % affiche 4 %
echo %b% % affiche 4 aussi,car 'b' est une référence à 'a' qui a été changée %
pause |
1/b/ comment créer une reference de reference:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @echo off
setlocal DisableDelayedExpansion
set a=3
set b=!a! % on créer une réference qui pointe vers 'a' %
set c=!b! % on créer une référence qui pointe vers 'b' %
setlocal EnableDelayedExpansion
set a=4
echo %a% % affiche 4 %
echo %b% % affiche 4 %
cmd /v /c echo %c% % affiche 4, on force l'expansion avec un sous shell %
pause |
un autre exemple:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| @echo off
setlocal DisableDelayedExpansion
set a=1
set c=2
set b=!a!
set a=!c!
setlocal EnableDelayedExpansion
% affiche 2 % echo %a%
% affiche 2 % cmd /v /c echo %b%
set a=18
% affiche 18 % echo %a%
% affiche 18 % cmd /v /c echo %b%
pause |
1/c/ comment savoir si une variable est une référence ou pas:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
@echo off
setlocal DisableDelayedExpansion
set a=3
set b=!a! % set b=K %
setlocal EnableDelayedExpansion
echo %a%
echo %b%
set a=4
echo %a%
echo %b%
if "!b!" NEQ "%b%" (echo REF) else (echo NO-REF)
pause |
2/ création d'un caractère LineFeed:
la commande SET ne permet pas seulement de créer de simple chaîne de caractères mais aussi elle permet d'injecter dans la variable des caractères spéciaux telque le caractère LF (retour à la ligne), pour ce faire on a aux moins deux possibilité
1 2 3 4 5 6 7 8 9 10
| @echo off
setlocal EnableDelayedExpansion
(Set \n=^
)
echo a!\n!b!\n!c
pause |
ou bien en combinant l'effet de pause avec set/P:
1 2 3 4 5 6 7 8 9 10
| @echo off
:)
setlocal enabledelayedexpansion
>nul,(pause&set /p LF=&pause&set /p LF=)<%0
set LF=!LF:~0,1!
echo a!LF!b!LF!c
pause |
SET/P
l'utilisation de la commande SET avec le commutateur /P permet de lire une ligne d'entrée à partir de la console. Vous pouvez l'utiliser pour inviter un utilisateur à entrer du contenu.
1/ simplification syntaxique
beaucoup de batcheurs utilisent cette syntaxe:
1 2
| echo entrez le nom du serveur
set /p server= |
on peux la simplifier ainsi:
set /p server=entrez le nom du serveur
2/ lire une/plusieurs ligne(s)
2/a/ lire une lgne:
on peux lire la première la première ligne d'un fichier et la stocker dans une variable:
1 2
| set /p ligne1=<c:\scripts\cmd\f1.txt
echo %ligne1% |
2/b/ exemple pratique:
afficher la longeur d'une chaine renvoyer par l'utilisateur ou un autre programme par le pipeline
length.cmd
1 2 3 4 5 6 7 8 9 10
| @echo off
set len=
set /p len=
for /f "skip=1 delims=:" %%i in ('"(set len&echo()|findstr /o ".*""') do set/a n=%%i-6
echo str: %len% len: %n%
exit /b
echo hello world| length.cmd |
2/b/ lire plusieurs lignes:
on peux aussi lire plusieurs lignes en chaînant des set/p:
1 2 3 4 5 6 7 8 9 10 11
|
(
set /p ligne1=
set /p ligne2=
set /p ligne3=
) < c:\scripts\cmd\f1.txt
echo %ligne3%
echo %ligne2%
echo %ligne1% |
2/c/ exemple pratique:
combiner le contenu de deux fichiers
1 2 3 4 5 6 7 8 9 10 11 12 13
| @echo off
Setlocal EnableExtensions DisableDelayedExpansion
(
for /f "delims=" %%a in (f1.txt) do (
set /p ligne=
setlocal enabledelayedexpansion
echo %%a - !ligne!
endlocal
)
) < f2.txt
endlocal |
sortie:
3/ conserver/supprimer les espaces du debut d'une ligne:
1 2 3 4
| (set spc= developpez.com)
set/p "=%spc%"<nul
echo(
set/p ="%spc%"<nul |
1 2
| developpez.com
developpez.com |
On peux utiliser cette technique pour supprimer les espaces au debut
d'une chaine de caractères on pourra utiliser cette technique par exemple dans une fonction PadLeft
4/ ligne sans CRLF:
il est possible d'utiliser SET/P pour avoir une chaine sans CRLF
1 2 3 4
| set /p=developpez.<nul
set /p=com<nul
> developpez.com |
SET/A
1/ renvoyer un résultat en une seule opération
on peux utiliser SET/A sans utiliser de variable:
2/ opérateur combinés:
En plus du simple opérateur d'assignation, il existe des "opérateurs combinés" pour tous les opérateurs arithmétiques
3/ Assignation multiple
si on a plusieurs variable qui partage le même contenu on peux simplifier l'assignation en utilisant une syntaxe spéciale
:: avant
1 2 3
| set /A i=5
set /A j=5
set /A k=5 |
:: maintenant
3/ decimal/ octal/ hexadecimal
SET/A supporte nativement les nombres octales et hexadecimal:
1 2 3
| set /a hex=0xA * 0xB
set /a oct=015 |
on pourra par exemple créer une simple fonction HexaToDec/OctToDec pour convertir entre les différents bases
4/ plus besoin d'activer l'expansion retardé de variables:
on peux utiliser les variables numériques dans des block de codes sans activer l'expansion retardé de variables, en utilisant cette syntaxe
:: le problème
1 2 3 4 5 6 7 8
|
@echo off
(
set h=10
set w=20
set /a a=%h% * %w%
)
echo %a% |
:: activer l'expansion retardé des variables
1 2 3 4 5 6 7 8 9
| @echo off
setlocal enabledelayedexpansion
(
set h=10
set w=20
set /a a=!h! * !w!
)
echo %a% |
:: sans activer l'expansion retardé des variables:
1 2 3 4 5 6 7 8
| @echo off
(
set h=10
set w=20
set /a a=h * w
)
echo %a% |
5/ injecter la valeur d'une equation dans une autre variable:
1 2
| set a=60,b=20
for /f %%x in ('"set /a (a-b)/4"') do set c=%%x |
6/ utilisation du modulo:
l'opérateur modulo est très pratique en scripting, son utilisation la plus courante est dans les traitement et formatge de donnée par alternance, par exemple:
"mettre une ligne vide pour chaque n lignes"
"afficher les ligne paire/impaire d'un fichier"
..etc
mais faite attention de ne pas utiliser le modulo avec de grands nombres:
va retouner "-1" au lieu de "0"
6/a/ exemple pratique:
traitement sur chaque N ligne
1 2 3 4 5 6 7 8 9 10 11
| f1.txt
ligne 1
ligne 2
ligne 3
ligne 4
ligne 5
ligne 6
ligne 7
ligne 8
ligne 9 |
1 2 3 4 5 6 7 8 9 10 11
| @echo off
set /a chaque_N_ligne=2
for /f "delims=" %%x In (f1.txt) Do (
set /a "z+=1,o=z %% (chaque_N_ligne+1)"
setlocal enabledelayedexpansion
if !o! equ 0 (echo(---- %%x) else echo(%%x
endlocal
)
pause |
sortie:
1 2 3 4 5 6 7 8 9
| ligne 1
ligne 2
---- ligne 3
ligne 4
ligne 5
---- ligne 6
ligne 7
ligne 8
---- ligne 9 |
7/ opérateurs binaire:
7/a/ opérateurs de décalage logique à gauche "SHL" et droite "SHR":
les deux décalage sont identiques mais ils utilisent des sens opposés, pour résoudre l'opération de décalage on peux multiplier ou diviser par 2:
1 2
| SHL
% 32 % set /A set /A 8 "<<" 2 |
est identique à
1 2
| SHR
% 1 % set /A 8 ">>" 3 |
est identique à
7/b/ exemple pratique:
chercher le nombre maximal et minimal d'une liste:
1 2 3 4 5 6 7 8 9 10 11
| @echo off
set list=1 99485 0 54 9054555 78
set /a max=0
set /a min=2147483647
for %%x in (%list%) do set /a max+="!((%%x-max)>>31)*(%%x-max),min-=!((min-%%x)>>31)*(min-%%x)"
echo %max%
echo %min%
pause |
7/c/ opérateur sur les bits:
L'aspect pratique de ces opérateurs est multiple, l'un d'eux est de faire des tests combiner avec des entires , il faut savoir aussi que l'execution d'une expression numérique avec des opérateurs de bits est plus rapide que l'execution avec une autre expression parce que les opérateurs de bits utilisent le language de la machine directement.
voici un exemple d'utilisation:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @echo off
Set Ville=TUNIS
set /a TUNIS = 1,PARIS = 2,ROME = 4,ALGER = 8,CAIRE = 16,LONDRES = 32
set /a MaVilleFavorite = "TUNIS | LONDRES | ALGER"
REM Ces Trois villes sont mes favorites
set /a P="MaVilleFavorite & %Ville%"
if %P% NEQ 0 (
echo %Ville% est parmis mes villes favorites [bmasks: %P%]
) else (
echo %Ville% n'est pas parmis mes villes favorites
)
pause |
voici un autre exemple:
verifier si un nombre est une puissance de 2
1 2 3 4 5 6 7 8 9 10 11
|
@echo off
for %%a in (8 9 7 32 180 200 16 512) do (
Call :PowerOf2 %%a && echo %%a
)
exit /b
:PowerOf2
set /A b="(%1 & (%1 - 1))"
exit /b %b% |
décortiquant ensemble l'expression numérique précédente:
on envoie un entier comme paramètre %1 à l'expression
set /A b="(%1 & (%1 - 1))"
on prendra le premier paramètre comme exemple '8'
simplifiant maintenant l'expression
l'opérateur '&' va traduire notre '8' et '7' en leurs representations binaire:
puis va faire une opération de comparaison spécial: si les deux valeurs sont égale à 1 alors le resultat est 1, autrement c'est 0.
autrement dit:
1 2 3 4 5 6 7 8
| set /a 1 "&" 1
> 1
set /a 0 "&" 1
> 0
set /a 1 "&" 0
> 0
set /a 0 "&" 0
> 0 |
donc 1000 & 0111 = 0000 => 0
alors la variable %b% contiendra un '0'
le '0' couplé à la commande 'exit' va mettre l'errorlevel à '0' ce que signifie que l'instruction est 'VRAI'
ensuite on aurra
Call PowerOf2 %%a : execution de l'instruction
&& : verifier l'instruction précédente si elle est 'VRAI' alors continuer
echo %%a : afficher la valeur de la variable %%a
=> affichage de 8
7/d/ Opérateur de complément:
en interne cette opérateur va convertir le nombre décimal en binaire puis va inverser les bits enfin va ajouter +1 au nombre trouvé:
7/e/ exmple pratique:
créer une fonction "xnor"
1 2 3 4 5 6
|
:XNOR_Func
set /a int1=5
set /a int2=7
set /a result="~(int1 ^ int2)"
echo %int1% XNOR %int2% = %result% |
8/ groupement:
il faut savoir aussi que le positionnement des parenthèses est important dans l'evaluation d'une expression
1 2 3 4
| set /a a=(5+3) * 2
echo %a% % 16 %
set /a b=5 + 3 * 2
echo %b% % 11 % |
9/ chaîner les expression:
si on a une longue expression utilisant plus d'une variables, on peux chaîner cette expression et la rendre compacte
exemple
10/ les espaces ne posent plus de problème:
avec la commande SET/A on n'a plus besoin de verifier/supprimer les espace de trop on peux utiliser notre commande ainsi:
ou bien
@suivre
Partager