for-loopbatch-filewildcardcommand-promptwildcard-expansion

Prevent Windows command-interpreter (FOR) from treating list as wildcards?


I am trying to write a batch file that takes a couple of arguments, followed by one or more optional filenames (which may include wildcards) and at some point processes each one of the optional filenames, but the for command keeps trying to expand them, so even so much as just printing them won’t work.

I checked the help (for /?), but there does not seem to be any switches to prevent this. I tried using single, double, and back-quotes as well as /f, but nothing seems to work.

The following command works as one would expect:

> for %i in (foo bar baz) do @echo %i
foo
bar
baz

The following command does not:

> for %i in (foo bar baz really?) do @echo %i
foo
bar
baz

The following, even less so:

> ren > reallyz
The syntax of the command is incorrect.

> dir /b really*
reallyz

> for %i in (foo bar baz really?) do @echo %i
foo
bar
baz
reallyz

Is there a way to get the Windows command-interpreter to treat the passed list as strings and not try to interpret it as filename wildcards?


Solution

  • No - the simple FOR command will always expand the * and ? wild card characters.

    You need to use a GOTO loop to do what you want. The SHIFT command enables access to all parameters.

    @echo off
    :argLoop
    if "%~1" neq "" (
      echo %1
      shift /1
      goto :argLoop
    )
    

    Most likely you want to do more with the arguments then just print them. Typically you would store them in an "array" of variables for later use.

    @echo off
    setlocal
    
    set argCnt=1
    :argLoop
    if "%~1" neq "" (
      set "arg.%argCnt%=%~1"
      set /a argCnt+=1
      shift /1
      goto :argLoop
    )
    set /a argCnt-=1
    
    :: Show Args
    setlocal enableDelayedExpansion
    for /l %%N in (1 1 %argCnt%) do echo arg.%%N = !arg.%%N!