Comment puis-je obtenir le résultat d’une commande dans une variable dans Windows?

Je cherche à obtenir le résultat d’une commande en tant que variable dans un script batch Windows (voir comment obtenir le résultat d’une commande dans bash pour l’équivalent de 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.

    Si vous devez capturer toutes les sorties de commandes, 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 VAR séparées par “!”.

    @ John: y a-t-il une utilisation pratique pour cela? Je pense que vous devriez regarder PowerShell ou tout autre langage de programmation capable d’effectuer facilement des tâches de script (Python, Perl, PHP, Ruby)

    L’humble pour le commandement 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=" remplace les délimiteurs d’espace et de tabulation par défaut, de sorte que la sortie de la commande de date soit engloutie en une seule fois.

    Pour capturer une sortie multi-ligne, il peut toujours être essentiellement un one-liner (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 canalisée, utilisez ^| :

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

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

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

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

    Voici une solution pour plusieurs lignes avec "array":

     @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 voudrez peut-être envisager de migrer vers un autre shell plus puissant ou créer une application pour ce genre de choses. Cela augmente considérablement les possibilités des fichiers batch.

    vous devez utiliser la commande SET avec le paramètre /P et y diriger votre sortie. Par exemple, voir http://www.ss64.com/nt/set.html . Travaillera pour CMD, pas sûr des fichiers .BAT

    D’un commentaire à ce post:

    Ce lien a la commande ” Set /P _MyVar= " qui indique qu'il va définir _MyVar sur la première ligne de MyFilename.txt . Cela pourrait être utilisé comme " myCmd > tmp.txt " avec " set /P myVar= ". Mais il n'obtiendra que la première ligne de la sortie, pas toute la sortie

    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 le double préfixe dans la variable loop:

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

    Si vous recherchez la solution fournie dans Utilisation du résultat d’une commande en tant qu’argument dans bash?

    alors voici le code:

     @echo off if not "%1"=="" goto get_basename_pwd for /f "delims=X" %%i in ('cd') do call %0 %%i for /f "delims=X" %%i in ('dir /o:d /b') do echo %%i>>%filename%.txt goto end :get_basename_pwd set filename=%~n1 :end 
    • Cela s’appellera lui-même avec le résultat de la commande CD, comme pwd.
    • L’extraction de chaînes sur les parameters renverra le nom du fichier / dossier.
    • Récupère le contenu de ce dossier et ajoute le nom de fichier.txt

    [Crédits] : Merci à toutes les autres réponses et quelques recherches sur la page des commandes de Windows XP .

     @echo off ver | find "6.1." > nul if %ERRORLEVEL% == 0 ( echo Win7 for /f "delims=" %%a in ('DIR "C:\Program Files\Microsoft Office\*Outlook.EXE" /B /P /S') do call set findoutlook=%%a %findoutlook% ) ver | find "5.1." > nul if %ERRORLEVEL% == 0 ( echo WinXP for /f "delims=" %%a in ('DIR "C:\Program Files\Microsoft Office\*Outlook.EXE" /B /P /S') do call set findoutlook=%%a %findoutlook% ) echo Outlook dir: %findoutlook% "%findoutlook%" 

    Utilisez simplement le résultat de la commande FOR . Par exemple (dans un fichier de commandes):

     for /F "delims=" %%I in ('dir /b /ad /od FILESA*') do (echo %%I) 

    Vous pouvez utiliser %%I comme valeur souhaitée. Juste comme ça: %%I

    Et à l’avance, le %%I n’ai pas d’espaces ou de caractères CR et peut être utilisé pour des comparaisons !!

    Vous pouvez capturer toutes les sorties dans une variable, mais les lignes seront séparées par un caractère de votre choix (# dans l’exemple ci-dessous) au lieu d’un CR-LF réel.

     @echo off setlocal EnableDelayedExpansion for /f "delims=" %%i in ('dir /b') do ( if "!DIR!"=="" (set DIR=%%i) else (set DIR=!DIR!#%%i) ) echo directory contains: echo %DIR% 

    Deuxième version, si vous devez imprimer le contenu ligne par ligne. Cela prend en compte le fait qu’il n’y aura pas de lignes de sortie en double à partir de “dir / b”, donc cela pourrait ne pas fonctionner dans le cas général.

     @echo off setlocal EnableDelayedExpansion set count=0 for /f "delims=" %%i in ('dir /b') do ( if "!DIR!"=="" (set DIR=%%i) else (set DIR=!DIR!#%%i) set /a count = !count! + 1 ) echo directory contains: echo %DIR% for /l %%c in (1,1,%count%) do ( for /f "delims=#" %%i in ("!DIR!") do ( echo %%i set DIR=!DIR:%%i=! ) ) 

    Je voudrais append une remarque aux solutions ci-dessus:

    Toutes ces syntaxes fonctionnent parfaitement si VOTRE COMMANDE EST TROUVÉE DANS LE CHEMIN ou SI LA COMMANDE EST UN cmdpath SANS ESPACES OU CARACTÈRES SPÉCIAUX.

    Mais si vous essayez d’utiliser une commande exécutable située dans un dossier dont le chemin contient des caractères spéciaux, vous devrez placer votre chemin de commande entre guillemets (“) et la syntaxe FOR / F ne fonctionnera pas.

    Exemples:

     $ for /f "tokens=* USEBACKQ" %f in ( `""F:\GLW7\Dissortingb\System\Shells and scripting\f2ko.de\folderbrowse.exe"" Hello '"F:\GLW7\Dissortingb\System\Shells and scripting"'` ) do echo %f The filename, directory name, or volume label syntax is incorrect. 

    ou

     $ for /f "tokens=* USEBACKQ" %f in ( `"F:\GLW7\Dissortingb\System\Shells and scripting\f2ko.de\folderbrowse.exe" "Hello World" "F:\GLW7\Dissortingb\System\Shells and scripting"` ) do echo %f 'F:\GLW7\Dissortingb\System\Shells' is not recognized as an internal or external command, operable program or batch file. 

    ou

     `$ for /f "tokens=* USEBACKQ" %f in ( `""F:\GLW7\Dissortingb\System\Shells and scripting\f2ko.de\folderbrowse.exe"" "Hello World" "F:\GLW7\Dissortingb\System\Shells and scripting"` ) do echo %f '"F:\GLW7\Dissortingb\System\Shells and scripting\f2ko.de\folderbrowse.exe"" "Hello' is not recognized as an internal or external command, operable program or batch file. 

    Dans ce cas, la seule solution que j’ai trouvée pour utiliser une commande et stocker son résultat dans une variable consiste à définir (temporairement) le répertoire par défaut sur celui de la commande elle-même:

     pushd "%~d0%~p0" FOR /F "tokens=* USEBACKQ" %%F IN ( `FOLDERBROWSE "Hello world!" "F:\GLW7\Dissortingb\System\Layouts (print,display...)"` ) DO (SET MyFolder=%%F) popd echo My selected folder: %MyFolder% 

    Le résultat est alors correct:

     My selected folder: F:\GLW7\Dissortingb\System\OS install, recovery, VM\ Press any key to continue . . . 

    Bien sûr, dans l’exemple ci-dessus, je suppose que mon script de traitement par lots est situé dans le même dossier que celui de ma commande exécutable afin que je puisse utiliser la syntaxe “% ~ d0% ~ p0”. Si ce n’est pas votre cas, vous devez trouver un moyen de localiser votre chemin de commande et de modifier le répertoire par défaut.

    NB: Pour ceux qui se demandent, l’exemple de commande utilisé ici (pour sélectionner un dossier) est FOLDERBROWSE.EXE. Je l’ai trouvé sur le site Web f2ko.de ( http://f2ko.de/en/cmd.php ).

    Si quelqu’un a une meilleure solution pour ce type de commandes accessibles via un chemin complexe, je serai très heureux d’en entendre parler.

    Gilles

    Veuillez vous référer à cette http://technet.microsoft.com/en-us/library/bb490982.aspx qui explique ce que vous pouvez faire avec la sortie de commande.