33

I have this for loop to get a list of directory names:

for /d %%g in (%windir%\Assembly\gac_msil\*policy*A.D*) do (
echo %%g
)

Output:

C:\WINDOWS\Assembly\gac_msil\policy.5.0.A.D
C:\WINDOWS\Assembly\gac_msil\policy.5.0.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.5.20.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.5.25.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.5.35.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.5.55.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.5.60.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.5.70.A.D.O
C:\WINDOWS\Assembly\gac_msil\policy.6.0.A.D.O

I want to get the folder names starting with "policy" but echo %%g:~29 doesn't work. I also tried to set x=%%g and then echo %x:~29% and still doesn't work.

So, how do I get substring from token in for loop?

4 Answers 4

52

Of course that set x=%%g and a substring extraction of x should work, but be aware that if the substring is taken inside a FOR loop, it must be done with ! instead of % (Delayed Expansion):

setlocal EnableDelayedExpansion
for /d %%g in (%windir%\Assembly\gac_msil\*policy*A.D*) do (
set x=%%g
echo !x:~29!
)
Sign up to request clarification or add additional context in comments.

4 Comments

useful tips here, thanks. Helped me write a script which I didn't think was possible.
@Aacini Is it possible to extract a substring directly from the parameter %%g, without using an auxiliary variable x and without enabling DelayedExpansion?
@AlfredoCapobianchi: Short answer: No. Long answer: if you carefully read the question, you should note this phrase: "echo %%g:~29 doesn't work".
You saved my day also! The usage of setlocal EnableDelayedExpansion along "!" is what works inside a for loop
9

On the other hand, if you want to know "How to get the last part (name and extension) of a token in for loop", the answer is: use the ~Name and ~eXtension modifiers in %%g replaceable parameter:

for /d %%g in (%windir%\Assembly\gac_msil\*policy*A.D*) do (
echo %%~NXg
)

3 Comments

Thanks. I'm sure that'll come in handy someday.
Can you expand on how this actually works? I wanna do the same thing but I want all filenames (not just "policy" ones). I tried * and \*.* but it breaks on spaces and gives unexpected results.
@RayCheng Wow, searched/experimented for a good hour or so regarding how to substring iterate-variables in a for loop. And then you show up and go all "oh and btw here is how you do it using 2 magic letters". This was exactly what i was looking for, thanks for saving my day :)
2

I recently had a similar question, and I wanted to compile here the 3 working solutions:

  1. Use EnableDelayedExpansion in your batch file, as in the accepted answer

    @echo off
    setlocal EnableDelayedExpansion
    for /d %%g in (%windir%\Assembly\gac_msil\*) do (
     set x=%%g
     echo !x:~29!
    )
    
  2. Use for /f to process the output of a dir command

    for /f "tokens=*" %%g in ('dir /ad /b %windir%\Assembly\gac_msil\*') do @echo %%g
    
  3. And finally, the optimal solution in this case, using enhanced variable substitution. See the end of the help at for /? for more information on this syntax.

    for /d %%g in (%windir%\Assembly\gac_msil\*) do @echo %%~nxg
    

Comments

1

A simple

dir /B %windir%\Assembly\gac_msil\*policy*A.D*

should do the trick. If you want to loop over it:

for /f %%g in ('dir /B %windir%\Assembly\gac_msil\*policy*A.D*') do (
    echo %%g
)

3 Comments

Neat! I'll use your suggestion but marked Aacini's as answer since that solution made me learn more.
Can you expand on how this actually works? I wanna do the same thing but I want all filenames (not just "policy" ones). I tried * and \*.* but it breaks on spaces and gives unexpected results.
@laggingreflex: So you want dir /B %windir%\Assembly\gac_msil\ - that should list all files in that directory?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.