3

I have .txt files (1 or more) in a directory that I want my batch file to read their filename, get 20 characters starting from the 4th and creating a new directory in the folder. Here is my code:

for /f %%i in ('dir /b *.TXT') do (
    set filename1=%%i
    set folder1=%filename1:~4,20%
    mkdir %folder1%
)

When I run this program the 1st time, I get a syntax not correct error for the line 3rd line (set folder1=....) and no folder is created. I tried running it a 2nd time and 2 folders were created (one named "~4" and one named "20"). On the 3rd run, the folder was correctly created! If I close the command prompt and open it again, it also needs to run 3 times before it creates the folder.

I've also tried using "for /r . $$i in (*.TXT) with no luck. As I understand, the problem is that the line with "set folder1=..." does not get the proper filename. I've also tried using %%~i or %%~ni, I've tried outputing the filename (which seems to always get the correct string) to a text file and then reading from that file, again with no luck. I don't know what else to try. Is it because %%i stores the file itself and not a string with the filename?

A sample file is named "REG_18004247K_20120208_A.TXT" and I want a folder to be created with the name "18004247K_20120208_A".

I am not at all familiar with batch programming (I'm only working with batch files for like 2 weeks) and I'm guessing the problem might be something really simple. Any help would be appreciated.

Kyriacos

Kyris
  • 95
  • 1
  • 9

2 Answers2

4

%%i does stores a string with a filename. It is actually the only "variable" that works as expected here.

The key problem is that you are using environment variable substitution (of filename1 and of folder1) inside a loop, hoping that it will be expanded in each iteration of the loop.

However, environment variables are expanded before execution of the whole loop begins.

  1. So, upon the first batch execution, filename1 is not defined and you get an error, folder1 is not set, and you probably also see a folder called %folder1% created.
  2. However, the scripts defines filename1 at this time, and the second execution gets further to define folder1 correctly (although line 4 was already expanded using the incorrect value and fun happens).
  3. The third execution finally gets to see the right value of folder1; but this would obviously not work for more than one file, as the loop logic is dysfunctional.

This older answer explains this problem with great other examples and special cases.

Your batch can be fixed by setlocal enabledelayedexpansion at the beginning of the script, initializing the variables to empty strings before the loop, and switching to the !...! syntax when expanding them: !filename1:~4,20!, and !folder1!.

Community
  • 1
  • 1
Jirka Hanika
  • 13,301
  • 3
  • 46
  • 75
1
setlocal enabledelayedexpansion
for /r %%i in (*) do (
    set filename1=%%i
    set folder1=!filename1:~4,20!
    mkdir !folder1!
)

Because ... delayed expansion takes some time to store actual variable.
!...! rather than %...% echoes fast allocating variables to DOS.

biegleux
  • 13,179
  • 11
  • 45
  • 52