2

Well... I try to dabble in batch as little as possible, and I'm mainly a C/C#/C++ man. My problem is that my script does two nested FOR loops where I run through the 'Users' folder first and snag the user names and then through other folders:

 set BaseDir=%CD%
 cd C:\Users
 for /F %%I in ('DIR *.* /B /O:-D') do (
     set UserName=%%I
     echo %UserName%
 )
 cd %BaseDir%

This roughly demonstrates the problem. Maybe it's my C++ style formatting? Maybe I'm dumb when it comes to batch? Assuming I have 3 users on my system (Admin, User1, User2; in that order) this will print:

 Admin
 Admin
 Admin

Totes wrong. If one were to call echo on %%I everything would go according to plan:

 Admin
 User1
 User2

Am I missing something here as far as variables go, or what's the deal? DOS doesn't like variable re-assignment? Thnx in advance. (specs: Windows 7, notepad, cmd as admin)

4
  • You might be having a conflict with the predefined username variable. What happens if you change that variable from UserName to UserName2 (or similar) Commented Sep 8, 2011 at 19:48
  • Wut? I actually just solved my problem facepalm. The solution is "elusive". One has to set Delayed Expansion... basically, it's like we're back in 1969... Commented Sep 8, 2011 at 19:53
  • I believe me saying the answer in my head telepathically went to you while I was typing my answer 0.o Commented Sep 8, 2011 at 19:55
  • Also note that you should use cd /D or pushd instead of just cd. The code as written won't work if C isn't the current drive. Commented Sep 8, 2011 at 22:32

2 Answers 2

2

Since you are changing a variable within the FOR loop, you need to enable delayed expansions:

SETLOCAL ENABLEDELAYEDEXPANSION
cd C:\Users
for /F %%I in ('DIR *.* /B /O:-D') do (
 set UserName=%%I
 echo %UserName%
)

EDIT A neat way to assign the variables separately to access each instance outside of the loop

SETLOCAL ENABLEDELAYEDEXPANSION
SET count=1
    cd C:\Users
    for /F %%I in ('DIR *.* /B /O:-D') do (
     set UserName!count!=%%I
     echo %UserName!count!%
     set count=!count!+1
    )
Sign up to request clarification or add additional context in comments.

1 Comment

Indeed, I stumbled on this conclusion almost immediately after I posted... This should be something posted under the documentation. It's bound to be something everyone has to learn once.
2

Another option is to use a subroutine:

 pushd C:\Users
 for /F %%I in ('DIR *.* /B /O:-D') do call :perfile %%I
 popd
 goto :eof

 :perfile
 set UserName=%*
 echo %UserName%
 goto :eof

Also note the use of pushd and popd to avoid needing to store the original directory in an environment variable.

Comments

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.