Como definir comandos de saída como uma variável em um arquivo em lotes

242

É possível definir a saída de uma instrução de um arquivo em lotes para uma variável, por exemplo:

findstr testing > %VARIABLE%

echo %VARIABLE%
Dennis
fonte
2
possível duplicata de lote equivalente de backticks Bash
Cristian Ciupitu
Na verdade, o original parece ser Como obtenho o resultado de um comando em uma variável no Windows? .
Cristian Ciupitu
possível duplicação de arquivos em lotes
Nathan
outro duplicado apenas por diversão: o Windows saída Atribuir lote de um programa para uma variável
icc97

Respostas:

275
FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
SET var=%%F
)
ECHO %var%

Eu sempre uso o USEBACKQ para que, se você tiver uma string para inserir ou um nome de arquivo longo, possa usar aspas duplas sem estragar o comando.

Agora, se sua saída contiver várias linhas, você poderá fazer isso

SETLOCAL ENABLEDELAYEDEXPANSION
SET count=1
FOR /F "tokens=* USEBACKQ" %%F IN (`command`) DO (
  SET var!count!=%%F
  SET /a count=!count!+1
)
ECHO %var1%
ECHO %var2%
ECHO %var3%
ENDLOCAL
Mechaflash
fonte
3
Trabalhou para mim no sistema Win7, obrigado! (e sim, são 7 anos de utilidade) PS Não esqueça de expandir% para %% nos comandos!
Dmitry Ilukhin
Isso funciona muito bem ... a menos que a saída contém exclamação pontos, uma vez que estes serão interpretados como caracteres de controle ao usar (!)ENABLEDELAYEDEXPANSION
JonathanDavidArndt
Funciona bem, exceto se você precisar usar |, caso em que não funciona.
Matt Vukomanovic
6
@MattVukomanovic ele trabalha para mim usando ^|no lugar de |, como descrito aqui
AST
É possível capturar o código de saída de commandqualquer maneira, por favor? Tenho certeza de que está retornando um código diferente de zero, mas %ERRORLEVEL%sempre contém 0, não importa onde eu tente usá-lo (mesmo dentro do dobloco). Então, acho que parte dessa forconstrução está sobrescrevendo-a. BTW É inacreditável o quão louco é o código necessário para algo tão elementar.
David Ferenczy Rogožan
68

Eu encontrei este tópico nessa coisa da Interweb. Tudo se resume a:

@echo off 
setlocal enableextensions 
for /f "tokens=*" %%a in ( 
'VER' 
) do ( 
set myvar=%%a 
) 
echo/%%myvar%%=%myvar% 
pause 
endlocal 

Você também pode redirecionar a saída de um comando para um arquivo temporário e, em seguida, colocar o conteúdo desse arquivo temporário em sua variável, como segue. Porém, ele não funciona com entrada de várias linhas.

cmd > tmpFile 
set /p myvar= < tmpFile 
del tmpFile 

Crédito para o segmento no hardware de Tom.

dolphy
fonte
3
A única desvantagem da abordagem de baixo para cima (que é preferível em todas as outras formas) é que ela não funciona com saída de várias linhas.
dgo 29/11/16
Para VER eu iria de outra forma: para / f "tokens = 2 delims = [,]" %% a in ( 'ver') fazer set version %% a echo% versão%
Hardoman
1
você é o segundo resultado para likesuchashereby - imagebin.ca/v/4NPSlQFgifce #
Shmuel Kamensky
Seu segundo exemplo me ajudou bastante ao escrever um arquivo em lotes para verificar a versão do chromedriver.exe versus um arquivo de texto que contém um número de versão. Eu sou um dinossauro DOS antigo e não sabia das opções para o comando set. As outras coisas foram um exagero para mim.
Bill Hileman
47

em uma única linha:

FOR /F "tokens=*" %g IN ('*your command*') do (SET VAR=%g)

a saída do comando será definida em% g e depois em VAR.

Mais informações: https://ss64.com/nt/for_cmd.html

Yuri
fonte
19
Meu lote não foi executado com "% g". Foi executado com "%% g".
Santiago Villafuerte
5
+ Santiago Villafuerte: sim, se você estiver executando em um arquivo em lotes, mas se desejar executá-lo na linha de comando (por exemplo: para testá-lo antes de colocá-lo no arquivo em lotes), use um único%.
Brent Rittenhouse
19

Para ler um arquivo ...

set /P Variable=<File.txt

Para escrever um arquivo

@echo %DataToWrite%>File.txt

Nota; ter espaços antes do caractere <> faz com que um espaço seja adicionado no final da variável, também

Para adicionar a um arquivo, como um programa de logger, primeiro crie um arquivo com uma única tecla Enter, chamada e.txt

set /P Data=<log0.log
set /P Ekey=<e.txt
@echo %Data%%Ekey%%NewData%>log0.txt

seu log ficará assim

Entry1
Entry2 

e assim por diante

Enfim, algumas coisas úteis


fonte
Obrigado pela sua resposta. Entre "set / P Variable = <File.txt" lê apenas a primeira linha do arquivo
Deepscorn
18

Essas respostas foram todas tão próximas da resposta que eu precisava. Esta é uma tentativa de expandir neles.

Em um arquivo em lote

Se você estiver executando de dentro de um .batarquivo e desejar uma única linha que permita exportar um comando complicado como jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.jsonuma variável chamada, AWS_ACCESS_KEYentão você deseja:

FOR /F "tokens=* USEBACKQ" %%g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%%g")

Na linha de comando

Se você estiver C:\pronto, deseje uma única linha que permita executar um comando complicado, como jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.jsonuma variável chamada, AWS_ACCESS_KEYentão você deseja:

FOR /F "tokens=* USEBACKQ" %g IN (`jq -r ".Credentials.AccessKeyId" c:\temp\mfa-getCreds.json`) do (SET "AWS_ACCESS_KEY=%g")

Explicação

A única diferença entre as duas respostas acima é que, na linha de comando, você usa um único% na sua variável. Em um arquivo em lotes, é necessário dobrar os sinais de porcentagem (%%).

Como o comando inclui dois pontos, aspas e parênteses, você precisa incluir a USEBACKQlinha nas opções para poder usar aspas para especificar o comando a ser executado e, em seguida, todos os tipos de caracteres engraçados dentro dele.

Ryan Shillington
fonte
13

Se você não deseja gerar um arquivo temporário e depois ler uma variável, esse código armazena o resultado do comando diretamente em uma variável:

FOR /F %i IN ('findstr testing') DO set VARIABLE=%i
echo %VARIABLE%

Se você deseja colocar a string de pesquisa entre aspas duplas:

FOR /F %i IN ('findstr "testing"') DO set VARIABLE=%i

Se você deseja armazenar esse código em um arquivo em lotes, adicione um símbolo% adicional:

FOR /F %%i IN ('findstr "testing"') DO set VARIABLE=%%i

Um exemplo útil para contar o número de arquivos em um diretório e armazenar em uma variável: (ilustra a tubulação)

FOR /F %i IN ('dir /b /a-d "%cd%" ^| find /v /c "?"') DO set /a count=%i

Observe o uso de aspas simples em vez de aspas duplas "ou acento grave` nos suportes de comando. Este é alternativa mais limpa para delims, tokensou usebackqem forloop.

Testado em Win 10 CMD.

Zimba
fonte
1
cd %windir%\system32\inetsrv

@echo off

for /F "tokens=* USEBACKQ" %%x in (      
        `appcmd list apppool /text:name`
       ) do (
            echo|set /p=  "%%x - " /text:name & appcmd.exe list apppool "%%x" /text:processModel.identityType
       )

echo %date% & echo %time%

pause
Dado
fonte
Não vejo como isso resolve a questão. appcmdnão é um programa padrão e não consigo ver onde você atribui a saída do programa a uma variável. Por fim, você precisa de mais explicações.
jeb
-3

Eu testei assim e funcionou:

SET /P Var= | Cmd

Ao canalizar o comando para uma variável, o prompt inserirá o resultado do comando " Cmd" na variável " Var".

Atualizar:

Não funciona, meu mal, o script que fiz foi o seguinte:

SET /P Var= | dir /b *.txt
echo %Var%

Na verdade, ele estava mostrando digamos " test.txt", mas na verdade estava mostrando o resultado do dir /b *.txtcomando " ", não o echo %var%. Fiquei confuso, pois as duas saídas eram as mesmas.

QcAlexN
fonte
3
Se você pretendia pipe the command into a variable prompt, deveria ter escrito dir /b *.txt | SET /P Var=para obter a direção correta do tubo. PS: Também não funciona assim!
Jesse Chisholm
-18

Espero que esta ajuda

set a=%username%
echo %a%    
set a="hello"
echo %a%
Ben2014
fonte
5
Não, isso não responde à pergunta. A questão está prestes a obter a saída de um comando em uma variável
jeb
A maneira mais fácil é gravar em um arquivo e lê-lo nesse arquivo. findstr "teste" test.txt> conjunto testoutput.txt /pa=<testoutput.txt echo% a%
Ben2014