158 votes

Comment obtenir le résultat d'une commande dans une variable sous Windows ?

Je cherche à obtenir le résultat d'une commande en tant que variable dans un script batch Windows (cf. comment obtenir le résultat d'une commande en bash pour l'équivalent en script bash). Une solution qui fonctionne dans un fichier .bat est préférable, mais d'autres solutions de script Windows courantes sont également les bienvenues.

12 votes

John, c'est ridiculement difficile de trouver ça. très question utile. Pourriez-vous envisager d'ajouter des formulations alternatives telles que Comment capture le site sortie de a a programme dans une variable dans un fichier batch Windows ?

3 votes

Google a affiché cette page en 3ème position.

2 votes

95voto

tardate Points 6809

L'humble pour La commande a accumulé quelques capacités intéressantes au fil des ans :

D:\> FOR /F "delims=" %i IN ('date /t') DO set today=%i
D:\> echo %today%
Sat 20/09/2008

Notez que "delims=" écrase les délimiteurs d'espace et de tabulation par défaut de sorte que la sortie de la commande date soit engloutie en une seule fois.

Pour capturer une sortie multi-lignes, il peut toujours s'agir essentiellement d'une seule ligne (en utilisant la variable lf comme délimiteur dans la variable résultante) :

REM NB:in a batch file, need to use %%i not %i
setlocal EnableDelayedExpansion
SET lf=-
FOR /F "delims=" %%i IN ('dir \ /b') DO if ("!out!"=="") (set out=%%i) else (set out=!out!%lf%%%i)
ECHO %out%

Pour capturer une expression pipée, utilisez ^| :

FOR /F "delims=" %%i IN ('svn info . ^| findstr "Root:"') DO set "URL=%%i"

1 votes

Comme pour la réponse de @PabloG, cela ne fonctionnera que pour obtenir la dernière ligne de sortie de la commande, "date /t" dans ce cas.

13 votes

J'ai trouvé que votre réponse ne fonctionnait que lorsque j'utilisais des signes doubles de pourcentage, c'est-à-dire FOR /F "delims=" %%i IN ('date /t') DO set today=%%i

23 votes

@Rabarberski : Si vous tapez une for directement sur la ligne de commande, vous utilisez une seule commande % . Si vous l'utilisez dans un fichier batch, vous utilisez %% .

39voto

PabloG Points 9308

Si vous devez capturer toute la sortie de la commande, vous pouvez utiliser un lot comme celui-ci :

@ECHO OFF
IF NOT "%1"=="" GOTO ADDV
SET VAR=
FOR /F %%I IN ('DIR *.TXT /B /O:D') DO CALL %0 %%I
SET VAR
GOTO END

:ADDV
SET VAR=%VAR%!%1

:END

Toutes les lignes de sortie sont stockées dans des VAR séparés par des " !".

Mais si une sortie console d'une seule ligne est attendue, essayez :

@ECHO off
@SET MY_VAR=
FOR /F %%I IN ('npm prefix') DO @SET "MY_VAR=%%I"

@REM Do something with MY_VAR variable...

@John : y a-t-il une utilité pratique à cela ? Je pense que tu devrais regarder PowerShell ou tout autre langage de programmation capable d'effectuer des tâches de script facilement (Python, Perl, PHP, Ruby).

0 votes

La réponse en une seule ligne résoudra le cas spécifique que j'ai. Je pensais simplement qu'il existait une option à plusieurs lignes (ou une option plus simple à une ligne). Je suppose que les capacités des fichiers bat ne sont pas si grandes. J'en ai besoin pour les scripts bat qui enveloppent les applications Java. Construire des classpaths principalement.

0 votes

Soyez très prudent avec cela. GWT a également essayé d'utiliser des fichiers batch pour démarrer Java avec des classpaths spécifiques, ce qui a échoué de manière horrible dès que vous arrivez à des répertoires avec des caractères non-ASCII (dans ce cas, c'était ma maison :)). Ils ont depuis réécrit cela avec VBS.

35 votes

Y a-t-il une utilité pratique à cela ? Vous plaisantez ? C'est utilisé tout le temps dans d'autres shells (tous ceux de GNU/Linux je suppose) et c'est très utile.

27voto

Evil Activity Points 632

Pour obtenir le répertoire courant, vous pouvez utiliser ceci :

CD > tmpFile
SET /p myvar= < tmpFile
DEL tmpFile
echo test: %myvar%

Il utilise un fichier temporaire, donc ce n'est pas le plus joli, mais ça marche ! CD' place le répertoire courant dans 'tmpFile', 'SET' charge le contenu de tmpFile.

Voici une solution pour les lignes multiples avec des "tableaux" :

@echo off

rem ---------
rem Obtain line numbers from the file
rem ---------

rem This is the file that is being read: You can replace this with %1 for dynamic behaviour or replace it with some command like the first example i gave with the 'CD' command.
set _readfile=test.txt

for /f "usebackq tokens=2 delims=:" %%a in (`find /c /v "" %_readfile%`) do set _max=%%a
set /a _max+=1
set _i=0
set _filename=temp.dat

rem ---------
rem Make the list
rem ---------

:makeList
find /n /v "" %_readfile% >%_filename%

rem ---------
rem Read the list
rem ---------

:readList
if %_i%==%_max% goto printList

rem ---------
rem Read the lines into the array
rem ---------
for /f "usebackq delims=] tokens=2" %%a in (`findstr /r "\[%_i%]" %_filename%`) do set _data%_i%=%%a
set /a _i+=1
goto readList

:printList
del %_filename%
set _i=1
:printMore
if %_i%==%_max% goto finished
set _data%_i%
set /a _i+=1
goto printMore

:finished

Mais vous devriez peut-être envisager de passer à un autre shell plus puissant ou de créer une application pour ce genre de choses. Cela étend un peu les possibilités des fichiers batch.

0 votes

Existe-t-il une variante qui fonctionne pour capturer plusieurs lignes de la commande ?

6 votes

Pour obtenir le répertoire courant, vous pouvez utiliser echo %CD%.

9voto

Ilya Kochetov Points 11641

Vous devez utiliser le SET avec le paramètre /P et dirigez votre sortie vers elle. Par exemple, voir http://www.ss64.com/nt/set.html . Cela fonctionnera pour CMD, mais pas pour les fichiers .BAT.

D'un commentaire à ce post :

Ce lien contient la commande " Set /P _MyVar=<MyFilename.txt "qui dit qu'il fixera _MyVar à la première ligne de MyFilename.txt . Cela pourrait être être utilisé comme " myCmd > tmp.txt " avec " set /P myVar=<tmp.txt ". Mais cela ne fera que la première ligne de la sortie, pas toute toute la sortie

2 votes

Ce lien contient la commande "Set /P _MyVar=<MyFilename.txt" qui indique que _MyVar sera la première ligne de MyFilename.txt. Cela pourrait être utilisé comme "myCmd > tmp.txt" avec "set /P myVar=<tmp.txt". Mais cela ne donnera que la première ligne de la sortie, pas toute la sortie.

0 votes

Cette réponse est pour les débutants comme moi

4voto

PabloG Points 9308

Exemple pour définir dans la variable d'environnement "V" le fichier le plus récent

FOR /F %I IN ('DIR *.* /O:D /B') DO SET V=%I

dans un fichier batch, vous devez utiliser un double préfixe dans la variable de la boucle :

FOR /F %%I IN ('DIR *.* /O:D /B') DO SET V=%%I

3 votes

J'ai déjà vu cette approche, mais elle me semble très peu pratique. Elle présente également le problème de ne capturer que la dernière ligne de sortie de la commande dans la variable.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X