Boucle for, la boucle à tout faire

SIO > S1_Commun > S1C3_Langage de commande > S1C3_DOS_4_for.md

Introduction

Pour faire des boucles, la commande goto montre vite ses limites car on ne peux par faire de vrais traitements sur des listes d'objets ou de lignes de fichiers.
Pour cela, on utilise (en DOS) la commande FOR.

Format :

[dos]
FOR /sel %%i IN () DO commande

Cette boucle exécute différents traitements selon le sélecteur.

  • sans sélecteur : parcours d'une liste de valeurs donnée entre les parenthèses,
  • /L : boucle incrémentale, le parenthèses contiennent les bornes et le pas d'incrément,
  • /D : parcours d'une liste de répertoires donnée entre parenthèse,
  • /R s'ajoute à /D : traiter aussi le contenu des répertoires donnés dans (…)
  • /F ["options"] : traitement d'un ensemble de fichiers en découpant les ligne selon les paramètres indiqués entre crochets
    • On ajoute […] derrière le sélecteur pour ajouter des options : délimiteur, fin de ligne, etc.
    • (…) peut aussi commande dans le but de traiter son retour, si on ajoute des guillemets simples autour de la commande : ('commande')

Attention : il y a 2 fois le signe % : %%i, %%a, etc... devant les variables de comptage, un de plus que pour les paramètres.

Usage des sélecteurs simples

Parcourir un ensemble de valeurs

POUR chaque valeur, FAIRE la commande

[dos]
FOR %%i IN (valeur1 valeur2) DO echo %%i 	// Affiche chaque valeur

Le traitement (Echo) est fait pour chaque valeur contenue dans la liste entre parenthèse.
La FOR donne successivement la valeur de chaque élément de la liste à la variable %%i puis exécute la commande après le DO pour chacune de ces valeurs.

Boucle incrémentale

POUR i de début à fin par pas de p FAIRE la commande

[dos]
# Format : FOR /L %%variable IN (index de début, pas, index de fin) DO commande
FOR /L %%i IN (1,2,10) DO @echo %%i 	// pour %%i=1 à 10 par pas de 2 => affiche les chiffres 1, 3, 5, 7 et 9

Traiter une liste de répertoires

POUR chaque répertoire de la liste FAIRE la commande

Afficher le contenu de chaque répertoire cité : rep1 et 2 et tout répertoire commençant par "test".

[dos]
FOR /D %%i IN (rep1 rep2 test* ) DO dir "%%i"


La seule différence avec la première boucle est que la liste peut contenir des jokers. La liste sera alors dataillée pour chaque nom de répertoire trouvé correspondant au gabarit.

Traiter récursivement une liste de répertoires

Afficher le contenu de chaque répertoire et sous répertoires commençant par "test" :

[dos]
FOR /R /D %%i IN (test* ) DO dir "%%i"


Les répertoires qui ne correspondent pas au gabarit sont ignorés.

Traiter le contenu d'un fichier

Le fonctionnement de cette commande est un peu plus complexe.

[dos]
FOR /F ["options"] %variable IN (ensemble de fichiers) DO commande

Les options sont entourées de " et " et sont dans l'ordre :

  • usebackq : indique qu'on utilise des back quotes (`) pour récupérer le retour d'une commande,
  • eol = caractère représentant la fin de la ligne (end of line)
  • skip=nombre de lignes exclues au début
  • tokens=numéros des colonnes à utiliser, séparés par virgules[]
  • delims=ensemble de caractères de délimitation des champs. Attention, si on laisse un espace avant le " de fin, il comptera comme un délimiteur.

Exemple de traitement d'un fichier

Avec un fichier texte structuré (par exemple un fichier texte ou csv)

[dos]
FOR /F "eol=# tokens=2,3,4* delims=;" %%a IN (monfich.txt) DO echo %%a, %%b, %%c

Dans ce code :

  • eol=# : le caractère # représente la fin optionnelle de la ligne, c'est à dire que tout ce qui est après est ignoré (commentaire)
  • tokens=1,3,4* : utiliser les colonnes 1, 3 et les colonnes à partir de 4 sont traitées en un seul bloc
  • delims=; : le point virgule est le délimiteur de champs

Soit le fichier suivant, contenant les identifiants et mdp d'utilisateur dont il faut créer une base de données :

# login;mdp;prénom et nom;description
toto;T0t0;Totoro Miyazaki ; secrétraire de gestion
titi;T1t1;Titeuff Chappuis; responsable qualité
tata;T4t4;Taram Alexander ; ingénieur des méthodes


La commande suivante effectue la création de l'utilisateur et sa base de données :

[dos]
FOR /F "eol=# tokens=1,2,3* delims=;" %%a IN (monfich.txt) DO (
   echo traitement de %%a : %%c
   mysql -uroot -proot mysql -e CREATE USER %%a IDENTIFIED BY '%%b';
   mysql -uroot -proot mysql -e CREATE DATABASE %%a ;
)

On remarque que chaque champ est placé automatiquement dans une variable alphabétique suivant celle indiquée dans la commande FOR.

Explications

  • La commande FOR analyse chaque ligne du fichier et découpe la ligne selon les options,
  • pour chaque ligne, FOR exécute les commandes contenues dans le DO :
    • un affichage,
    • la création de l'utilisateur avec la commande mysql
    • la création de sa base de données.

Dans ce script, il faudrait aussi accorder des privilèges à l'utilisateur sur sa base de données.

Exemple de traitement du retour d'une cde

Nous allons compter le nombre de fichiers .txt

[dos]
@echo off
set /A count=0
 
FOR /F %%a IN ('DIR /B *.txt 2^>NUL') DO set /A count=count+1
 
IF %count% GTR 1 (
   echo Trouvé %count% fois ! 
) else ( 
   echo Aucun fichier trouvé 
)

Explications

  • La commande suivante extrait les noms seuls (/B) et envoye l'affichage des erreurs à la poubelle

[dos]
DIR /B *.txt 2^>NUL

  • La commande exécutée après le DO calcule l'incrémentation de 1 pour chaque boucle.
  • L'alternative (IF) permet d'afficher le résultat de façon plus sympa que le simple résultat.

Conclusion

DOS : pratique mais limité

  • Commande simples : efficace
  • prog structurée : difficile à maîtriser

Shell Linux

  • très efficace et complet, c'est un vrai langage de programmation
  • Très utilisé ... sous linux,

Powershell

  • Beaucoup plus souple que DOS,
  • très complet et véritable langage de programmation,
  • de très nombreuses comandes et bibliothèques de fonctions permettent d'en faire un outil incotournable de la gestion des serveurs Windows ... et Linux !
  • Orienté objet donc l'écriture est parfois plus complexe à déchiffrer

Continuons dans cette voie : Powershell 1