How does “FOR” work in cmd batch file?

前端 未结 12 1032
面向向阳花
面向向阳花 2020-12-03 10:40

I\'ve been programming in dozens of languages for 20 years but I could never understand how \"FOR\" work in windows cmd shell batch file, no matter how hard I tried. I read

相关标签:
12条回答
  • 2020-12-03 10:54

    I know this is SUPER old... but just for fun I decided to give this a try:

    @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
    

    This doesn't require a count and will go until it finishes. I had the same problem with spaces but it made it through the entire variable. The key to this is the loop labels and the SHIFT function.

    0 讨论(0)
  • 2020-12-03 10:59

    for /f iterates per line input, so in your program will only output first path.

    your program treats %PATH% as one-line input, and deliminate by ;, put first result to %%g, then output %%g (first deliminated path).

    0 讨论(0)
  • 2020-12-03 11:03

    This works for me:

    @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
    
    0 讨论(0)
  • 2020-12-03 11:05

    You have to additionally use the tokens=1,2,... part of the options that the for loop allows. This here will do what you possibly want:

    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")
    

    This example processes the first 12 tokens (=directories from %path%) only. It uses explicit enumeration of each of the used tokens. Note, that the token names are case sensitive: %a is different from %A.

    To be save for paths with spaces, surround all %x with quotes like this "%i". I didn't do it here where I'm only echoing the tokens.

    You could also do s.th. like this:

    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 )
    

    This one skips tokens 2,4,6 and uses a little shortcut ("7-26") to name the rest of them. Note how %c, %b, %a are processed in reverse order this time, and how they now 'mean' different tokens, compared to the first example.

    So this surely isn't the concise explanation you asked for. But maybe the examples help to clarify a little better now...

    0 讨论(0)
  • 2020-12-03 11:06

    None of the answers actually work. I've managed to find the solution myself. This is a bit hackish, but it solve the problem for me:

    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 ! I hate batch file programming !!

    Updated

    Mark's solution is simpler but it won't work with path containing whitespace. This is a little-modified version of Mark's solution

    echo off
    setlocal enabledelayedexpansion
    set NonBlankPath=%PATH: =#%
    set TabbedPath=%NonBlankPath:;= %
    for %%g in (%TabbedPath%) do (
      set GG=%%g
      echo !GG:#= !
    )
    
    0 讨论(0)
  • 2020-12-03 11:06

    Here is a good guide:

    FOR /F - Loop command: against a set of files.

    FOR /F - Loop command: against the results of another command.

    FOR - Loop command: all options Files, Directory, List.

    [The whole guide (Windows XP commands):

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

    Edit: Sorry, didn't see that the link was already in the OP, as it appeared to me as a part of the Amazon link.

    0 讨论(0)
提交回复
热议问题