Como faço para obter o resultado de um comando em uma variável no windows?

Eu estou olhando para obter o resultado de um comando como uma variável em um script em lotes do Windows (veja como obter o resultado de um comando no bash para o bash scripting equivalente). Uma solução que funcionará em um arquivo .bat é a preferida, mas outras soluções comuns de script do Windows também são bem-vindas.

Se você tiver que capturar toda a saída do comando, você pode usar um 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 as linhas de saída são armazenadas em VAR separadas por “!”.

@ John: há algum uso prático para isso? Eu acho que você deve assistir o PowerShell ou qualquer outra linguagem de programação capaz de executar tarefas de script facilmente (Python, Perl, PHP, Ruby)

Os humildes por comando acumularam algumas capacidades interessantes ao longo dos anos:

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

Note que "delims=" sobrescreve o espaço padrão e os delimitadores de tabulação para que a saída do comando date seja devorado de uma só vez.

Para capturar a saída de várias linhas, ele ainda pode ser essencialmente um one-liner (usando a variável lf como o delimitador na variável 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 uma expressão canalizada, use ^| :

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

Para obter o diretório atual, você pode usar isto:

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

Está usando um arquivo temporário, então não é o mais bonito, mas certamente funciona! 'CD' coloca o diretório atual em 'tmpFile', 'SET' carrega o conteúdo do tmpFile.

Aqui está uma solução para várias linhas com "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 

Mas você pode querer considerar mudar para outro shell mais poderoso ou criar um aplicativo para essas coisas. Está esticando bastante as possibilidades dos arquivos em lote.

você precisa usar o comando SET com o parâmetro /P e direcionar sua saída para ele. Por exemplo, consulte http://www.ss64.com/nt/set.html . Irá trabalhar para o CMD, não tenho certeza sobre os arquivos .BAT

De um comentário para este post:

Esse link tem o comando ” Set /P _MyVar= ", que diz que irá definir _MyVar para a primeira linha de MyFilename.txt . Isso pode ser usado como " myCmd > tmp.txt " com " set /P myVar= ". Mas só vai conseguir a primeira linha da saída, nem toda a saída

Exemplo para definir na variável de ambiente “V” o arquivo mais recente

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

em um arquivo de lote, você tem que usar o prefixo duplo na variável de loop:

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

Se você está procurando a solução fornecida em Usando o resultado de um comando como um argumento no bash?

então aqui está o 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 
  • Isso se chamará com o resultado do comando CD, igual ao pwd.
  • A extração de string em parâmetros retornará o nome do arquivo / pasta.
  • Obtenha o conteúdo desta pasta e acrescente ao nome do arquivo.txt

[Créditos] : Obrigado a todas as outras respostas e a algumas pesquisas na página de comandos do 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%" 

Apenas use o resultado do comando FOR . Por exemplo (dentro de um arquivo de lote):

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

Você pode usar o %%I como o valor desejado. Apenas assim: %%I .

E com antecedência o %%I não tem espaços ou caracteres CR e pode ser usado para comparações !!

Você pode capturar todas as saídas em uma variável, mas as linhas serão separadas por um caractere de sua escolha (# no exemplo abaixo) em vez de um 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 versão, se você precisar imprimir o conteúdo de linha a linha. Isso leva vantagem do fato de que não haverá linhas duplicadas de saída de “dir / b”, portanto, pode não funcionar no caso geral.

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

Eu gostaria de acrescentar uma observação às soluções acima:

Todas essas syntaxs funcionam perfeitamente bem SE SEU COMANDO É ENCONTRADO DENTRO DO CAMINHO ou SE O COMANDO É UM cmdpath SEM ESPAÇOS OU PERSONAGENS ESPECIAIS.

Mas se você tentar usar um comando executável localizado em uma pasta cujo caminho contenha caracteres especiais, será necessário colocar seu caminho de comando entre aspas duplas (“) e, em seguida, a syntax FOR / F não funcionará.

Exemplos:

 $ 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. 

ou

 $ 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. 

ou

 `$ 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. 

Nesse caso, a única solução que encontrei para usar um comando e armazenar seu resultado em uma variável é definir (temporariamente) o diretório padrão para o do próprio 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% 

O resultado está correto:

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

É claro que no exemplo acima, eu assumo que meu script em lote está localizado na mesma pasta que o do meu comando executável, para que eu possa usar a syntax “% ~ d0% ~ p0”. Se esse não for o seu caso, você precisará encontrar uma maneira de localizar o caminho do comando e alterar o diretório padrão para seu caminho.

NB: Para aqueles que se perguntam, o comando de exemplo usado aqui (para selecionar uma pasta) é FOLDERBROWSE.EXE. Eu o encontrei no site f2ko.de ( http://f2ko.de/en/cmd.php ).

Se alguém tiver uma solução melhor para esse tipo de comando acessível através de um caminho complexo, ficarei muito feliz em ouvi-lo.

Gilles

Consulte este http://technet.microsoft.com/en-us/library/bb490982.aspx, que explica o que você pode fazer com a saída do comando.