Pergunta

Eu estou olhando para obter o resultado de um comando como uma variável em um script de lote do Windows (veja como obter o resultado de um comando em festa para o bash script equivalente). Uma solução que irá trabalhar em um arquivo .bat é o preferido, mas outras janelas de script comum soluções também são bem vindos.

Foi útil?

Solução

Se você tem de capturar toda a saída do comando que você pode usar um lote como esta:

@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 armazenados em VAR separados com "!".

@ John: existe alguma utilidade prática para isso? Eu acho que você deve prestar atenção PowerShell ou qualquer outra linguagem de programação capaz de realizar tarefas de script facilmente (Python, Perl, PHP, Ruby)

Outras dicas

O humilde comando acumulou alguns recursos 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=" substitui o espaço padrão e delimitadores de tabulação para que a saída do comando data fica devorado tudo de uma vez.

Para capturar a saída multi-linha, que ainda pode ser essencialmente uma única linha (utilizando o LF variável como 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 canalizado, uso ^|:

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%

Ele está usando um arquivo temporário, porém, portanto, não é o mais bonito, mas certamente funciona! 'CD' coloca o diretório atual no 'tmpfile', cargas 'set' o conteúdo de tmpfile.

Aqui está uma solução para várias linhas com "array de":

@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 a mudança para um outro mais poderoso shell ou criar uma aplicação para este material. É esticar as possibilidades dos arquivos em lote um pouco.

Você precisa usar o comando SET com o parâmetro /P e direcionar sua saída para ele. Por exemplo, ver http://www.ss64.com/nt/set.html . Vai trabalhar para CMD, não tenho certeza sobre .bat

A partir de um comentário a este post:

Esse link tem o "Set /P _MyVar=<MyFilename.txt" comando que diz que vai definir _MyVar para a primeira linha de MyFilename.txt. Isto pode ser usado como "myCmd > tmp.txt" com "set /P myVar=<tmp.txt". Mas ela só vai obter a primeira linha da saída, não toda a saída

Exemplo de conjunto 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 que você tem que usar double prefixo na variável de loop:

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

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

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

Você pode usar o %%I como o valor que você deseja. Assim como este:. %%I

E antecipadamente o %%I não tem nenhum espaços ou caracteres CR e pode ser usado para comparações !!

Se você está procurando a solução fornecida em Usando o resultado de um comando como um argumento em 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
  • Isto irá chamar-se com o resultado do comando CD, mesmo que pwd.
  • Cordas extração em parâmetros retornará a pasta / nome de arquivo.
  • Obter o conteúdo desta pasta e acréscimo para o filename.txt

[Créditos] : Graças a todas as outras respostas e algumas escavações na comandos do Windows XP página .

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

Eu gostaria de adicionar uma observação para as soluções acima:

Todos estes sintaxes funcionar perfeitamente bem se o seu comando é encontrado dentro do caminho ou se o comando é um cmdpath sem espaços ou caracteres especiais.

Mas se você tentar usar um comando executável localizado em uma pasta que caminho contém caracteres especiais, em seguida, você precisa colocar o seu caminho de comando em aspas ( ") e, em seguida, a sintaxe FOR / F não funciona.

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 eu encontrei para usar um comando e armazenar o resultado em uma variável é definir (temporariamente) o diretório padrão para o de 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 é então correta:

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

Claro que no exemplo acima, presumo que o meu script lote está localizado na mesma pasta como a de meu comando executável para que eu possa usar a sintaxe "% ~ d0% ~ p0". Se este não for o seu caso, então você tem que encontrar uma maneira de localizar o seu caminho de comando e altere 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 encontrei-o na f2ko.de web site ( http://f2ko.de/en/cmd.php ).

Se alguém tiver uma solução melhor para esse tipo de comandos acessível através de um caminho complexo, vou ser muito feliz em ouvir isso.

Gilles

Você pode capturar toda a saída em uma variável, mas as linhas serão separados por um caractere de sua escolha (# no exemplo abaixo) em vez de um real CR-LF.

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

A segunda versão, se você precisa imprimir o conteúdo fora de linha por linha. Isso leva advanted do fato de que não haverá linhas duplicadas de saída de "dir / b", por isso 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=!
    )
)
@echo off
setlocal EnableDelayedExpansion
FOR /F "tokens=1 delims= " %%i IN ('echo hola') DO (
    set TXT=%%i
)
echo 'TXT: %TXT%'

O resultado é 'TXT: Hola'

Você deve usar o comando for, aqui está um exemplo:

@echo off
rem Commands go here
exit /b
:output
for /f "tokens=* useback" %%a in (`%~1`) do set "output=%%a"

e você pode usar call :output "Command goes here" então a saída será na variável %output%.

Nota:. Se você tem uma saída de comando que é multilinha, esta ferramenta vai set a saída para a última linha de seu comando várias linhas

Por favor, consulte esta http://technet.microsoft.com/en -us / library / bb490982.aspx que explica o que você pode fazer com saída do comando.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top