Pergunta

Eu tenho programado em dezenas de idiomas para 20 anos, mas eu nunca poderia entender como "FOR" trabalho em janelas cmd arquivo de lote shell, não importa o quão duro eu tentei. Eu li

http://www.amazon.com/Windows-Administration-Command-Line- Vista / dp / 0470046163 / ref = sr_1_1? ie = UTF8 & s = livros & qid = 1241362727 & sr = 8-1

http://www.ss64.com/nt/for.html

e vários outros artigos sobre a internet, mas ainda confundem e não pode realizar qualquer coisa.

Alguém pode me dar uma explicação concisa sobre como "FOR" obras em geral?

Para uma pequena pergunta mais específica, como posso iterate através de cada caminho% PATH variável%? Eu tentei com

rem showpathenv.bat
for /f "delims=;" %%g in ("%PATH%") do echo %%g

Isso iria mostrar apenas o primeiro caminho, não todos eles. Por quê ? O que eu fiz de errado?

Foi útil?

Solução

Nenhuma das respostas realmente funcionar. Eu consegui encontrar a solução sozinho. Isto é um pouco hackish, mas resolver o problema para mim:

echo off
setlocal enableextensions
setlocal enabledelayedexpansion
set MAX_TRIES=100
set P=%PATH%
for /L %%a in (1, 1, %MAX_TRIES%) do (
  for /F "delims=;" %%g in ("!P!") do (
    echo %%g
    set P=!P:%%g;=!
    if "!P!" == "%%g" goto :eof
  )
)

Oh! Eu odeio programação arquivo de lote !!

Atualização

A solução de Mark é mais simples, mas não vai trabalhar com caminho que contém espaços em branco. Esta é uma versão modificada-pouco da solução de Mark

echo off
setlocal enabledelayedexpansion
set NonBlankPath=%PATH: =#%
set TabbedPath=%NonBlankPath:;= %
for %%g in (%TabbedPath%) do (
  set GG=%%g
  echo !GG:#= !
)

Outras dicas

A idéia de Mark era bom, mas talvez esqueceu algum caminho tem espaços entre eles. Substituir ';' com '" "' em vez iria cortar todos os caminhos em cadeias entre aspas.

set _path="%PATH:;=" "%"
for %%p in (%_path%) do if not "%%~p"=="" echo %%~p

Então aqui, você tem seus caminhos exibidos.

FOR comando no cmd tem uma curva de aprendizado tedioso, nomeadamente porque como as variáveis ??reagir dentro () 's declarações ... você pode atribuir qualquer variável, mas você não pode ler, em seguida, de volta dentro do ()' s, a menos que você usar a instrução "setlocal ENABLEDELAYEDEXPANSION", e, portanto, também usam as variáveis ??com !! 's em vez de %%' s (! _var!)

Eu atualmente exclusivamente script com cmd, para o trabalho, tive que aprender tudo isso:)

Você tem a idéia certa, mas for /f é projetado para trabalhar em arquivos multi-linha ou comandos, não cordas individuais.

Na sua forma mais simples, for é como for do Perl, ou foreach qualquer outra língua. Você passá-lo uma lista de tokens, e ele itera sobre eles, chamando o mesmo comando de cada vez.

for %a in (hello world) do @echo %a

As extensões apenas fornecem meios automáticos de construir a lista de tokens. A razão o seu código atual está chegando com nada é que ';' é o fim padrão de linha de símbolo (comentário). Mas mesmo se você mudar isso, você teria que usar %%g, %%h, %%i, ... para acesso as fichas individuais, que irão limitar severamente o seu arquivo em lotes.

O mais próximo que você pode chegar ao que você pedir é:

set TabbedPath=%PATH:;= %
for %%g in (%TabbedPath%) do echo %%g

Mas isso vai falhar por caminhos citados que contêm vírgulas.

Na minha experiência, for /l e for /r são bons para estender comandos existentes, mas de outra forma for é extremamente limitada. Você pode torná-lo um pouco mais poderosa (e confuso), com expansão de variáveis ??atrasada (cmd /v:on), mas é realmente bom apenas para listas de nomes de arquivos.

Eu sugiro usar WSH ou PowerShell se você precisa executar a manipulação de cadeia. Se você está tentando escrever whereis para Windows, tente where /?.

não pôde resistir jogando esta lá fora, velho como esta discussão é ... Normalmente, quando a necessidade surge para percorrer cada um dos arquivos em PATH, tudo que você realmente quer fazer é encontrar um determinado arquivo ... Se esse é o caso, este one-liner vai cuspir o primeiro diretório que encontra o seu arquivo em:

(ex: procura java.exe)

for %%x in (java.exe) do echo %%~dp$PATH:x

Eu sei que isto é SUPER idade ... mas apenas por diversão, decidi tentar dar um presente:

@Echo OFF
setlocal
set testpath=%path: =#%
FOR /F "tokens=* delims=;" %%P in ("%testpath%") do call :loop %%P
:loop
if '%1'=='' goto endloop
set testpath=%1
set testpath=%testpath:#= %
echo %testpath%
SHIFT
goto :loop
:endloop
pause
endlocal
exit

Esta não requer uma contagem e vai até que ele termine. Eu tive o mesmo problema com espaços, mas ele fez isso através de toda a variável. A chave para isso é as etiquetas de loop e a função SHIFT.

itera for /f por entrada de linha, por isso em seu programa exibirá somente a saída primeiro caminho.

seu programa trata% PATH% como entrada de uma linha, e DElimine por ;, coloque primeiro resultado a %% g, então a saída %% g (caminho primeira deliminated).

FOR é essencialmente iteração sobre as "linhas" no conjunto de dados. Neste caso, há uma linha que contém o caminho. O "delims=;" está apenas dizendo a ele para separar em ponto e vírgula. Se você alterar o corpo para echo %%g,%%h,%%i,%%j,%%k você verá que ele está tratando a entrada como uma única linha e dividi-lo em vários tokens.

Isso funciona para mim:

@ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
@REM insure path is terminated with a ;
set tpath=%path%;
echo.
:again
@REM This FOR statement grabs the first element in the path
FOR /F "delims=;" %%I IN ("%TPATH%") DO (
  echo    %%I 
  @REM remove the current element of the path
  set TPATH=!TPATH:%%I;=!
)
@REM loop back if there is more to do. 
IF DEFINED TPATH GOTO :again

ENDLOCAL

Você tem que usar adicionalmente a parte tokens=1,2,... das opções que o loop for permite. Este aqui vai fazer o que você possivelmente querer:

for /f "tokens=1,2,3,4,5,6,7,8,9,10,11,12 delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %b ^
   & echo. %a ^
   & echo. %c ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k ^
   & echo. ^
   & echo.   ...and now for some more... ^
   & echo. ^
   & echo. %a ^| %b ___ %c ... %d ^
   & dir "%e" ^
   & cd "%f" ^
   & dir /tw "%g" ^
   & echo. "%h  %i  %j  %k" ^
   & cacls "%f")

Este exemplo processa os primeiros 12 símbolos (= pastas do caminho%%) apenas. Ele usa a enumeração explícita de cada um dos símbolos usados. Note, que os nomes simbólicos são sensíveis:.% Um é diferente de% A

Para ser salvo por caminhos com espaços, bordadura todas % x com citações como esta "% i". Eu não fazê-lo aqui, onde eu estou apenas ecoando os tokens.

Você também pode fazer s.th de assim:

for /f "tokens=1,3,5,7-26* delims=;" %a in ("%PATH%") ^
do ( ^
     echo. %c ^
   & echo. %b ^
   & echo. %a ^
   & echo. %d ^
   & echo. %e ^
   & echo. %f ^
   & echo. %g ^
   & echo. %h ^
   & echo. %i ^
   & echo. %j ^
   & echo. %k )

este salta fichas 2,4,6 e usa um pouco de atalho ( "7-26"), para citar o resto deles. Nota como% C,% b, um% são processados ??em ordem inversa, desta vez, e como se agora 'médios' tokens diferentes, em comparação com o primeiro exemplo.

Então, isso certamente não é a explicação concisa você pediu. Mas talvez o exemplo ajuda a esclarecer um pouco melhor agora ...

Aqui está um guia bom:

FOR / F - comando Loop:. Contra um conjunto de arquivos

FOR / F - comando Loop:. Contra os resultados de outro comando

PARA - Circuito de comando:. Todas as opções de arquivos, diretório, uma lista

[Toda a guia (comandos do Windows XP):

http://www.ss64.com/nt/index.html

Editar:. Desculpe, não viu que o link já estava no OP, como apareceu para mim como parte do link Amazon

Ele funciona para mim, experimentá-lo.

for /f "delims=;" %g in ('echo %PATH%') do echo %g%

Ele funciona para mim, experimentá-lo.

for / f "tokens = * delims ="; % G em ( 'eco% PATH%') fazer eco% g%

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