matt beyond
matt beyond

Reputation: 71

For-loop in batch file is reading the input from file incorrectly - Loops failing

I have a for loop reading lines from a file called "temp". It should read each line and then proceed to create a directory for each name in the file. However, it's reading the first line of the file twice before it moves to the second line. So I get an error saying the folder already exists.

The file "temp" contains, for now, two entries:

folder1 
folder2

The code is simple:

for /F "tokens=*" %%i in  (temp) do  (
    set pstname=%%i
    echo the folder name is set to  %pstname%
    mkdir C:\output\%pstname%
)

When I run this, it reads the first line, folder1, from the "temp" file and creates the directory c:\output\folder1. So I expect that in the next iteration the variable pstname will be set to the second line in the "temp" file (should be set to folder2)

But that is not what happens. The loop reads fodler1 twice and attempts to create the folder1 folder again. If I continue with the script it eventually reads the second line from the "temp" file (folder2) and creates it. So the script almost works.

Issue: What am I doing wrong? It reads the first line in the file "temp" twice before it proceeds to the next line?

Is there a next command I have to use? What is wrong with my logic?

Upvotes: 1

Views: 3454

Answers (1)

Magoo
Magoo

Reputation: 79983

Look again. The second directory is NOT being created.

You are a victim of the "delayed expansion" problem. The ENTIRE command from the FOR though to the closing parenthesis is parsed and at that time, any %var% is replaced by the value of var as it stands at the time the line is PARSED. Only then is the line EXECUTED.

Hence, run your codefrag once, and pstname as it stands at that time is used as the target directory name - possibly empty (without the rest of you code, there's no way to tell.)

What is executed is thus (assuming pstname is empty)

for /F "tokens=*" %%i in  (temp) do  (
    set pstname=%%i
    echo the folder name is set to
    mkdir C:\output\
)

BUT pstname will acquire the name from the LAST line of the file.

IF you then run the code again without clearing pstname first, then you'll get

for /F "tokens=*" %%i in  (temp) do  (
    set pstname=%%i
    echo the folder name is set to  folder2
    mkdir C:\output\folder2
)

which will be executed twice - once for each line in temp - AND create that direcory.

There are plenty of references on SO to this problem. The easiest cure is

for /F "tokens=*" %%i in  (temp) do  (
    echo the folder name is set to  %%i
    mkdir "C:\output\%%i"
)

(Note rabbit's ears surrounding name to be created - accounts for spaces in names)

Upvotes: 2

Related Questions