Problema com a saída deste comando FOR

Problema com a saída deste comando FOR

Acabei de perceber que estou executando um arquivo bat no início desta chave de registro, que tinha echo running abce algumas outras coisas irrelevantes

HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\AutoRun

Então aqui eu modifiquei aquele arquivo bat. É apenas uma linha, nada irrelevante nele.

você vê o conteúdo do arquivo bat.

Aqui está uma saída do prompt do cmd mostrando a situação agora, que é o mesmo problema fundamental, mas você deve conseguir reproduzir o problema

A questão agora é:

  • Por que diz echo sss e não echo sss ttt?
  • Como posso suprimir a execução do cmd ou do arquivo bat de inicialização com o FOR? A instrução FOR deve exibir apenas "echo g", não "echo sss" ou "echo sss ttt".

Microsoft Windows XP [Version 5.1.2600]
(C) Copyright 1985-2001 Microsoft Corp.
sss ttt
C:\Documents and Settings\Administrator>cd\

C:\>type \blah\startfile.bat <ENTER>
@echo sss ttt   

C:\>  

C:\>for /f %f in ('echo g ^| findstr "g"') do echo %f <ENTER>

C:\>echo sss
sss

C:\>echo g
g

C:\>

Responder1

Por que diz echo sss e não echo sss ttt?

Porque a linha sss tttcontém um caractere de espaço. O forcomando tokeniza e armazena a primeira metade e sssa %fsegunda metade tttna %gvariável.

Como posso suprimir a execução do cmd ou do arquivo bat de inicialização com o FOR? A instrução FOR deve exibir apenas "echo g", não "echo sss" ou "echo sss ttt".

Parece que para avaliar echo g ^| findstr "g"um novo interpretador de comandos é inicializado e o seu \blah\startfile.baté executado automaticamente. Faça seu lote não produzir nada.

Responder2

Se for usar %fem um arquivo em lote, você precisa escapar dele com outro %:

for /f %%f in ('echo g ^| findstr "g"') do echo %%f

Coloque isso em seu arquivo em lote e você deverá obter os resultados que procura.

Responder3

Só para expandir um pouco a resposta de Vlastimil...

Quando oFORcomando executa o"echo g"e canaliza a saída parafindstr,PARAtem que primeiro iniciar um novo processador de comando que faz com que\blah\startfile.batpara ser executado.

\blá\startfile.batgera uma linha contendosss ttt. Essa linha é processada porPARAe éNÃOpassado paraencontrarstr.

De acordo com a ajuda paraPARA:

O processamento consiste em ..., dividi-lo em linhas individuais de texto e, em seguida, analisar cada linha em zero ou mais tokens. O corpo do loop for é então chamado com os valores das variáveis ​​definidos para a(s) string(s) do token encontrado(s). Por padrão, /F passa o primeiro token separado em branco de cada linha...

Os delimitadores padrão paraPARAsão:",;"(espaço, vírgula e ponto e vírgula).

A primeira linha quePARAprocessos contém a string:sss ttt. Essa string contém um" "(espaço), que é um delimitador padrão paraPARA, que analisa a linha e atribui a primeira string de token:"sss"para"%f". Então o"eco %f"gera uma linha com apenas:"sss". Essa é a primeira linha que você vê impressa. O"ttt"é simplesmente descartado porque o"PARA... eco %f"O comando não especificou incluir nada além do primeiro token.

Se oPARAcomando foi escrito de forma diferente, você teria visto a linha completa"sss ttt"ecoou.

Aqui estão três maneiras pelas quaisPARAcomando poderia ter sido escrito para fazer isso.

A primeira maneira, usando o"delims="opção, define o delimitador paraPARApara "vazio", entãoPARAretorna a linha inteira como 1 token. Os tokens ainda são analisados ​​e todos os delimitadores (",;") são removidos, então todos os tokens são combinados novamente com um espaço entre cada token. Este valor combinado é retornado na variável"%f"

C:\>for /f "delims=" %f in ('echo sss ttt')  do echo %f

C:\>echo sss ttt
sss ttt

C:\>for /f "delims=" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f

C:\>echo mm nn oo ss tt
mm nn oo ss tt

A próxima maneira, usando o"tokens=*"opção, dizPARApara colocar todos os tokens encontrados no valor da variável especificada ("%f"). Os tokens ainda são analisados ​​e todos os delimitadores são removidos e, em seguida, todos os tokens são combinados novamente com um espaço entre cada token.

C:\>for /f "tokens=*" %f in ('echo sss ttt')  do echo %f

C:\>echo sss ttt
sss ttt

C:\>for /f "tokens=*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo %f

C:\Users\1-kevin>echo mm nn oo ss tt
mm nn oo ss tt

Esta terceira forma, usando o"tokens=1,*"opção, dizPARApara colocar o primeiro (1) token encontrado no valor da variável especificada ("%f"). E, os tokens restantes são analisados ​​e todos os delimitadores são removidos, então todos os tokens restantes são combinados novamente com um espaço entre cada token, e esse valor combinado é retornado na variável nomeada com a letra que segue o nome da variável especificada (então neste caso, variável"%g").

C:\>for /f "tokens=1,*" %f in ('echo sss ttt')  do echo %f %g

C:\>echo sss ttt
sss ttt

C:\>for /f "tokens=1,*" %f in ('echo mm;nn,oo, ;ss ,, tt') do echo "%f" "%g"

C:\>echo "mm" "nn oo ss tt"
"mm" "nn oo ss tt"

Observe que o seguinte não funcionará porque não há "tokens=" definidos para variáveis ​​além da variável especificada de"%f":

C:\>for /f %f in ('echo sss ttt')  do echo %f %g

C:\>echo sss %g
sss %g


Então, no seu exemplo, se você adicionou o"delims="opção, você veria isto:

C:\>for /f "delims=" %f in ('echo g ^| findstr "g"') do echo %f

C:\>echo sss ttt
sss ttt

C:\>echo g
g

C:\>

informação relacionada