¿Cómo obtengo el resultado de un comando en una variable en Windows?

Estoy buscando obtener el resultado de un comando como una variable en un script por lotes de Windows (vea cómo obtener el resultado de un comando en bash para el equivalente de scripts bash). Se prefiere una solución que funcionará en un archivo .bat, pero también se aceptan otras soluciones comunes de script de Windows.

Si tiene que capturar todos los resultados del comando, puede usar un lote como este:

@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 

Todas las líneas de salida se almacenan en VAR separadas por “!”.

@John: ¿hay algún uso práctico para esto? Creo que debería ver PowerShell o cualquier otro lenguaje de progtwigción capaz de realizar tareas de scripting fácilmente (Python, Perl, PHP, Ruby)

El comando humilde ha acumulado algunas capacidades interesantes a lo largo de los años:

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

Tenga en cuenta que "delims=" sobrescribe el espacio predeterminado y los delimitadores de tabs para que la salida del comando de fecha se engulle todo a la vez.

Para capturar salidas de varias líneas, aún puede ser esencialmente un trazador de líneas (usando la variable lf como delimitador en la variable resultante):

 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% 

Para capturar una expresión canalizada, use ^| :

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

Para obtener el directorio actual, puede usar esto:

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

Sin embargo, está usando un archivo temporal, por lo que no es el más bonito, ¡pero ciertamente funciona! 'CD' coloca el directorio actual en 'tmpFile', 'SET' carga el contenido de tmpFile.

Aquí hay una solución para líneas múltiples con "array's":

 @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 

Pero es posible que desee considerar pasar a otro shell más potente o crear una aplicación para este tipo de cosas. Está ampliando las posibilidades de los archivos por lotes bastante.

necesita usar el comando SET con parameter /P y dirigir su salida hacia él. Por ejemplo, vea http://www.ss64.com/nt/set.html . Funcionará para CMD, no estoy seguro acerca de los archivos .BAT

De un comentario a esta publicación:

Ese enlace tiene el comando ” Set /P _MyVar= " que dice que establecerá _MyVar en la primera línea de MyFilename.txt . Esto podría usarse como " myCmd > tmp.txt " con " set /P myVar= ". Pero solo obtendrá la primera línea de la salida, no toda la salida

Ejemplo para establecer en la variable de entorno “V” el archivo más reciente

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

en un archivo por lotes, debe usar el prefijo doble en la variable de ciclo:

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

Si está buscando la solución provista en Usar el resultado de un comando como argumento en bash?

entonces aquí está el código:

 @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 
  • Esto se llamará a sí mismo con el resultado del comando CD, igual que pwd.
  • La extracción de cadena en los parámetros devolverá el nombre de archivo / carpeta.
  • Obtenga el contenido de esta carpeta y anexe al filename.txt

[Créditos] : gracias a todas las otras respuestas y algunas búsquedas en la página de comandos 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%" 

Simplemente use el resultado del comando FOR . Por ejemplo (dentro de un archivo por lotes):

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

Puede usar el %%I como el valor que desea. Justo como este: %%I

¡Y de antemano el %%I no tiene espacios ni caracteres CR y puede usarse para comparaciones!

Puede capturar todos los resultados en una variable, pero las líneas estarán separadas por un carácter de su elección (# en el ejemplo a continuación) en lugar de un CR-LF real.

 @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% 

Segunda versión, si necesita imprimir el contenido línea por línea. Esto se aprovecha del hecho de que no habrá líneas duplicadas de salida desde “dir / b”, por lo que puede no funcionar en el caso general.

 @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=! ) ) 

Me gustaría agregar una observación a las soluciones anteriores:

Todas estas syntax funcionan perfectamente bien SI SU COMANDO SE ENCUENTRA DENTRO DE LA RUTA O SI EL MANDO ES UN CAMINO DE cmD SIN ESPACIOS O CARACTERES ESPECIALES.

Pero si intenta utilizar un comando ejecutable ubicado en una carpeta cuya ruta contiene caracteres especiales, deberá encerrar la ruta del comando en comillas dobles (“) y luego la syntax FOR / F no funcionará.

Ejemplos:

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

o

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

o

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

En ese caso, la única solución que encontré para usar un comando y almacenar su resultado en una variable es establecer (temporalmente) el directorio predeterminado al del comando mismo:

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

El resultado es entonces correcto:

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

Por supuesto, en el ejemplo anterior, supongo que mi secuencia de comandos por lotes se encuentra en la misma carpeta que la de mi comando ejecutable para que pueda utilizar la syntax “% ~ d0% ~ p0”. Si este no es tu caso, entonces tienes que encontrar una manera de ubicar tu ruta de comando y cambiar el directorio predeterminado a su ruta.

Nota: Para aquellos que se preguntan, el comando de muestra utilizado aquí (para seleccionar una carpeta) es FOLDERBROWSE.EXE. Lo encontré en el sitio web f2ko.de ( http://f2ko.de/en/cmd.php ).

Si alguien tiene una mejor solución para ese tipo de comandos accesibles a través de una ruta compleja, estaré encantado de saber de ella.

Gilles

Consulte este http://technet.microsoft.com/en-us/library/bb490982.aspx que explica qué puede hacer con el resultado del comando.