Batch Windows: appeler plus d'une commande dans une boucle FOR?

124

Est-il possible dans le fichier de commandes Windows d'appeler plusieurs commandes dans une seule FOR boucle? Disons par exemple que je veux imprimer le nom du fichier et après le supprimer:

@ECHO OFF
FOR /r %%X IN (*.txt) DO (ECHO %%X DEL %%X)
REM the line above is invalid syntax.

Je sais que dans ce cas, je pourrais le résoudre en faisant deux boucles FOR distinctes: une pour afficher le nom et une pour supprimer le fichier, mais est-il possible de le faire en une seule boucle?

Marco Demaio
la source

Réponses:

117
FOR /r %%X IN (*) DO (ECHO %%X & DEL %%X)
SilverSkin
la source
2
En fait, je pense que les parenthèses ne sont pas nécessaires. for %i in (1 2 3) do echo %i & echo fooaffiche ce à quoi je m'attendais: "1", "foo", "2", "foo", "3", "foo" (sur des lignes séparées).
bk1e
Cela ne devrait-il pas être &&plutôt que &?
jww
9
@jww &&échouera si la première commande échoue, &exécutera la deuxième commande malgré tout.
yyny
Si cette solution fait une erreur de syntaxe pour vous, vérifiez si vous avez un paren sans échappement entre les DO-parens. Vous pouvez leur échapper en leur ajoutant un ^.
Константин Ван
199

L'utilisation &est bien pour les commandes courtes, mais cette seule ligne peut devenir très longue très rapidement. Lorsque cela se produit, passez à la syntaxe multiligne.

FOR /r %%X IN (*.txt) DO (
    ECHO %%X
    DEL %%X
)

Placement (et )questions. Les parenthèses rondes après DOdoivent être placées sur la même ligne, sinon le fichier batch sera incorrect.

Voir if /?|find /V ""pour plus de détails.

Anders
la source
12
Cette solution semble propre et lisible. Je voudrais également avertir tout programmeur qui utilise cette solution que le support rond après le ne DOdoit PAS être placé à la ligne suivante, sinon il freine le fichier de commandes. Dans le code, lorsque j'écris une boucle for, je place généralement la {ligne suivante entre accolades .
Marco Demaio
2
Aussi - méfiez-vous si l'une de vos commandes imbriquées a des crochets entre (par exemple, quelque chose comme "echo Something something (quelque chose d'autre)" EDIT: ah, voir la réponse de bk1e :)
Tim Barrass
31

SilverSkin et Anders ont tous deux raison. Vous pouvez utiliser des parenthèses pour exécuter plusieurs commandes. Cependant, vous devez vous assurer que les commandes elles-mêmes (et leurs paramètres) ne contiennent pas de parenthèses. cmdrecherche avidement la première parenthèse fermante, au lieu de gérer gracieusement les ensembles imbriqués de parenthèses. Cela peut entraîner l'échec de l'analyse du reste de la ligne de commande, ou certaines des parenthèses peuvent être passées aux commandes (par exemple DEL myfile.txt)).

Une solution de contournement consiste à diviser le corps de la boucle en une fonction distincte. Notez que vous devez probablement sauter autour du corps de la fonction pour éviter de "tomber" dedans.

FOR /r %%X IN (*.txt) DO CALL :loopbody %%X
REM Don't "fall through" to :loopbody.
GOTO :EOF

:loopbody
ECHO %1
DEL %1
GOTO :EOF
bk1e
la source
3
Tant que nous sommes sur le sujet,% X n'est jamais correct en ce qui concerne les noms de fichiers, utilisez toujours "% ~ X" (Dans votre exemple ici, vous pourriez probablement vous en tirer avec% * dans la sous-fonction)
Anders
1
C'est un très bon point. Un bon exemple de chemin qui démontre les deux problèmes est C:\Program Files (x86).
bk1e