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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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é

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
echo entrez le nom du serveur
set /p server=
on peux la simplifier ainsi:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
str: hello world len: 11
2/b/ lire plusieurs lignes:

on peux aussi lire plusieurs lignes en chaînant des set/p:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
(set spc=          developpez.com)
set/p "=%spc%"<nul
echo(
set/p ="%spc%"<nul

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
> set /? | findstr "+="


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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:


Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
set /a x=3333333333 % 3
va retouner "-1" au lieu de "0"

6/a/ exemple pratique:

traitement sur chaque N ligne

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
SHL
% 32 %  set /A set /A 8 "<<" 2
est identique à

Code : Sélectionner tout - Visualiser dans une fenêtre à part
% 32 %  set /A 8 * 2 * 2

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
SHR
% 1  %  set /A 8 ">>" 3
est identique à

Code : Sélectionner tout - Visualiser dans une fenêtre à part
% 1  %  set /A ((8/2)/2)/2
7/b/ exemple pratique:


chercher le nombre maximal et minimal d'une liste:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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


Code : Sélectionner tout - Visualiser dans une fenêtre à part
set /A b="(%1 & (%1 - 1))"
on prendra le premier paramètre comme exemple '8'

Code : Sélectionner tout - Visualiser dans une fenêtre à part
set /A b="(8 & (8 - 1))"
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:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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"
Code : Sélectionner tout - Visualiser dans une fenêtre à part
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

Code : Sélectionner tout - Visualiser dans une fenêtre à part
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