endo.anaconda
endo.anaconda

Reputation: 2468

nested for-loops result in wrong result

I have some problems with nested for-loops. as you see in the result, the correct line was loaded, but the second loop which splits up the line into two fields does somthing wrong

Any ideas ?

cheers endo

current output

line=user1|pass1
usr:   user2
pass:  pass2
 --------
line=user2|pass2
usr:   user2
pass:  pass2
 --------

pass.txt

user1|pass1
user2|pass2

batchfile

cls
@echo off &setlocal

for /f "tokens=*" %%a in (pass.txt) do (
  echo line=%%a
  set "string=%%a"  

    for /f "tokens=1,2 delims=|" %%i in ("%string%") do set "variable1=%%i" &set "variable2=%%j"
    echo usr:   %variable1%
    echo pass:  %variable2%
    endlocal

set "string="
echo. --------

)

Upvotes: 0

Views: 68

Answers (2)

aschipfl
aschipfl

Reputation: 34909

You could remove the (temporary) variable assignments and use the for variables "%%?" immediately as arguments for further commands if you want to avoid delayed expansion:

@echo off & cls
setlocal
for /f "tokens=*" %%a in (pass.txt) do (
    echo line=%%a
    for /f "tokens=1,2 delims=|" %%i in ("%%a") do (
        echo usr:   %%i
        echo pass:  %%j
        echo. --------
    )
)
endlocal

Another thought: for this approach you do not need two nested loops, because the FOR command is capable of splitting each read line of a text file immediately; try this:

@echo off & cls
setlocal
for /f "tokens=1,2 delims=|" %%a in (pass.txt) do (
    echo line=%%a^|%%b
    echo usr:   %%a
    echo pass:  %%b
    echo. --------
)
endlocal

Upvotes: 0

MC ND
MC ND

Reputation: 70923

Nested for loops are correctly working.

But what is not working (not as intended) are the variables. In batch script, each time a block (the lines enclosed in parenthesis) is reached, all variable reads are replaced with the value in the variable before the execution. If inside a block you need to access the value of a variable, and this value has been assigned/changed inside the block, then, it is necessary to indicate that the variable read should be delayed.

So, your code should be something like

@echo off  & cls
setlocal enabledelayedexpansion

for /f "tokens=*" %%a in (pass.txt) do (
  echo line=%%a
  set "string=%%a"

    for /f "tokens=1,2 delims=|" %%i in ("!string!") do set "variable1=%%i" &set "variable2=%%j"
    echo usr:   !variable1!
    echo pass:  !variable2!

echo. --------

)
endlocal

setlocal enabledelayexexpansion activates this feature, and %var% references are replaced (where needed) with !var! sintax, indicating variables that need delayed read.

Upvotes: 1

Related Questions