How does “FOR” work in cmd batch file?

前端 未结 12 1033
面向向阳花
面向向阳花 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 11:13

    Mark's idea was good, but maybe forgot some path have spaces in them. Replacing ';' with '" "' instead would cut all paths into quoted strings.

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

    So here, you have your paths displayed.

    FOR command in cmd has a tedious learning curve, notably because how variables react within ()'s statements... you can assign any variables, but you can't read then back within the ()'s, unless you use the "setlocal ENABLEDELAYEDEXPANSION" statement, and therefore also use the variables with !!'s instead of %%'s (!_var!)

    I currently exclusively script with cmd, for work, had to learn all this :)

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

    It works for me, try it.

    for /f "delims=;" %g in ('echo %PATH%') do echo %g%
    
    0 讨论(0)
  • 2020-12-03 11:15

    FOR is essentially iterating over the "lines" in the data set. In this case, there is one line that contains the path. The "delims=;" is just telling it to separate on semi-colons. If you change the body to echo %%g,%%h,%%i,%%j,%%k you'll see that it is treating the input as a single line and breaking it into multiple tokens.

    0 讨论(0)
  • Couldn't resist throwing this out there, old as this thread is... Usually when the need arises to iterate through each of the files in PATH, all you really want to do is find a particular file... If that's the case, this one-liner will spit out the first directory it finds your file in:

    (ex: looking for java.exe)

    for %%x in (java.exe) do echo %%~dp$PATH:x
    
    0 讨论(0)
  • 2020-12-03 11:19

    You've got the right idea, but for /f is designed to work on multi-line files or commands, not individual strings.

    In its simplest form, for is like Perl's for, or every other language's foreach. You pass it a list of tokens, and it iterates over them, calling the same command each time.

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

    The extensions merely provide automatic ways of building the list of tokens. The reason your current code is coming up with nothing is that ';' is the default end of line (comment) symbol. But even if you change that, you'd have to use %%g, %%h, %%i, ... to access the individual tokens, which will severely limit your batch file.

    The closest you can get to what you ask for is:

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

    But that will fail for quoted paths that contain semicolons.

    In my experience, for /l and for /r are good for extending existing commands, but otherwise for is extremely limited. You can make it slightly more powerful (and confusing) with delayed variable expansion (cmd /v:on), but it's really only good for lists of filenames.

    I'd suggest using WSH or PowerShell if you need to perform string manipulation. If you're trying to write whereis for Windows, try where /?.

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

    It works for me, try it.

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

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