¿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 scripting bash). Una solución que funcionará en a .se prefiere el archivo bat, pero otras soluciones comunes de scripting de Windows también son bienvenidas.

Author: Community, 2008-09-20

11 answers

Si tiene que capturar toda la salida 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ías ver PowerShell o cualquier otro lenguaje de programación capaz de realizar tareas de scripting fácilmente (Python, Perl, PHP, Ruby)

 25
Author: PabloG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 16:23:21

El humilde para comando 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 los delimitadores de espacio y tabulación predeterminados para que la salida del comando date se devore a la vez.

Para capturar la salida de varias líneas, todavía puede ser esencialmente una línea única (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"
 70
Author: tardate,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-14 23:45:09

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' pone el directorio actual en 'tmpFile', ' SET ' carga el contenido de tmpFile.

Aquí hay una solución para múltiples líneas con "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

Pero es posible que desee considerar mover a otro shell más potente o crear una aplicación para estas cosas. Está estirando las posibilidades de los archivos por lotes bastante trozo.

 21
Author: Evil Activity,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 16:49:38

Necesita usar el comando SET con el parámetro /P y dirigir su salida a él. Por ejemplo, véase http://www.ss64.com/nt/set.html . Funcionará para CMD, no estoy seguro.BAT files

De un comentario a este post:

Ese enlace tiene el comando "Set /P _MyVar=<MyFilename.txt " que dice que pondrá _MyVar en la primera línea de MyFilename.txt. Esto podría ser se usa como "myCmd > tmp.txt " con " set /P myVar=<tmp.txt". Pero sólo obtener la primera línea de la salida, no toda la salida

 6
Author: Ilya Kochetov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-22 08:22:10

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 doble prefijo en la variable de bucle:

FOR /F %%I IN ('DIR *.* /O:D /B') DO SET V=%%I
 4
Author: PabloG,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 15:27:46

Si está buscando la solución proporcionada en Usando 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 cadenas en los parámetros devolverá el nombre de archivo/carpeta.
  • Obtenga el contenido de esta carpeta y añádalo al nombre del archivo.txt

[Credits] : Gracias a todas las otras respuestas y algunas indagaciones sobre el Comandos de Windows XP página.

 2
Author: Gustavo Carreno,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:43
@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%"
 2
Author: Hike,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-06 00:34:18

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

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

Puede usar el %%I como el valor que desee. Así: %%I.

Y de antemano el %%I no tiene espacios o caracteres CR y se puede utilizar para comparaciones!!

 2
Author: Raceableability,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-30 10:51:43

Puede capturar toda la salida 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 toma advanted del hecho de que no habrá líneas duplicadas de salida de "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=!
    )
)
 1
Author: Adam Mitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 16:49:47

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

Todas estas sintaxis funcionan perfectamente BIEN SI EL COMANDO SE ENCUENTRA DENTRO DE LA RUTA o SI EL COMANDO ES UN cmdpath SIN ESPACIOS O CARACTERES ESPECIALES.

Pero si intenta usar un comando ejecutable ubicado en una carpeta cuya ruta contiene caracteres especiales, entonces necesitará encerrar su ruta de comando entre comillas dobles (") y entonces la sintaxis FOR /F no funciona.

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 propio comando:

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, asumo que mi script por lotes se encuentra en la misma carpeta que la de mi comando ejecutable para que pueda usar la sintaxis "%~d0%~p0". Si este no es tu caso, entonces tienes que encontrar una manera para localizar la ruta del comando y cambiar el directorio predeterminado a su ruta.

NB: Para aquellos que se preguntan, el comando de ejemplo 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 un camino complejo, estaré muy contento de escuchar de ella.

Gilles

 1
Author: Gilles Maisonneuve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-17 16:57:02

Por favor refiérase a esto http://technet.microsoft.com/en-us/library/bb490982.aspx que explica lo que se puede hacer con la salida de comandos.

 -1
Author: Jack B Nimble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-20 15:21:08