1

My Windows batch file is supposed to read file names and create a directory that is named according to the filename's 2nd to 5th letter:

for %%f in (.\*.txt) do (
set string=%%~nf
mkdir %string:~2,5%     
)

The value of 'string' is not updated though, i.e. it is the same in each step of the loop. How can I have it updated?

This is the cmd output:

>for %f in (.\*.txt) do (
set string=%~nf
 mkdir le3
)

>(
set string=file1
 mkdir le3
)

>(
set string=file2
 mkdir le3
)
A subdirectory or file le3 already exists.

>(
set string=file3
 mkdir le3
)
A subdirectory or file le3 already exists.
3
  • Try consulting the hundreds of articles on SO about delayedexpansion. Essentially, a %var% within a code block is replaced by the value of var when the block is parsed. To access the changing value within a block, you feed first to invoke delayedexpansion using a setlocal enabledelayedexpansion command, and then use !var! to access the dynamic value of the variable. Commented Sep 28, 2016 at 5:31
  • Thank you for your reply. I consulted several sites, e.g. link and came up with 'SETLOCAL ENABLEDELAYEDEXPANSION for %%f in (.*.txt) do ( set !string!=%%~nf mkdir !string:~2,5! )' - but the delayed expansion does not seem to work yet. Do you have any advice what's wrong? Commented Sep 28, 2016 at 8:05
  • set !string!=%%~nf should be set string=%%~nf - you intend to set the variable string, not the variable current content of string Commented Sep 28, 2016 at 13:43

2 Answers 2

1

The problem you're running into is because of %variable% expansion. The entire FOR statement (including up to the closing parenthesis) is one statement. When it is read, the command processor replaces the %string% variable with whatever string is set to before the SET inside executes. (Actually, you're getting the subset of string starting at the 2nd character and proceeding 5 characters, but that's not really important here. My guess is that you've got %string% set to "file3".)

Anyway, you can fix it by adding SETLOCAL ENABLEDELAYEDEXPANSION at the top and using syntax like !string! instead of %string% inside the FOR.

You could also move the processing of %string% outside of FOR.

Look up HELP SETLOCAL and HELP SET for more.

Also, if you hadn't noticed, you're not getting the second and fifth characters of the filename... As I mentioned, you're getting a substring of (up to) length 5, starting at character 2. Look up HELP SET for more.

Sign up to request clarification or add additional context in comments.

1 Comment

I have now enabled delayed expansion and adapted the code: SETLOCAL ENABLEDELAYEDEXPANSION for %%f in (.\*.txt) do ( set !string!=%%~nf mkdir !string:~2,5! ) I understand the idea, also tried setting the quotation marks in different places, but still I don't get the delayed expansion to work - Any ideas?
0

Nearly, you've got a couple of unnecessary exclamation marks in your last attempt:

SETLOCAL ENABLEDELAYEDEXPANSION
for %%f in (*.txt) do (
    set string=%%~nf
    if not exist "!string:~2,5!\" mkdir "!string:~2,5!"
)

1 Comment

I helps the site and prosective responders if you mark correct answers accordingly.

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.