Windows Batch For Loop - Variable not setting

EDIT: It appears I had a stray GOTO :EOF at the end of an ECHO statement, and it will actually GOTO :EOF... d'oh! Thanks for responses. I think the bug is squashed now.


I have a script where I want to roll through a text document comparing if the files match.

Script here:

setlocal enabledelayedexpansion
for /f "tokens=1* delims=\" %%a in (NoMatchA.txt) DO ( set "flag=" for /f "tokens=1* delims=\" %%i in (NoMatchB.txt) do ( IF "%%b"=="%%j" SET flag=1 ) IF DEFINED flag ECHO FLAG DEFINED IF NOT DEFINED flag ECHO FLAG NOT DEFINED
)
endlocal

made up Input from NoMatchA.txt and NoMatchB.txt made up example:

1234567890 \TEMP\ANIMALS\DOGS\FILE1.pdf
0987654321 \TEMP\TREES\I hate willows.docx
1122334455 \TEMP\LINUX ISOS\linustarvolds.iso
1029384756 \COVID\CANSUCk\MYBALLS\prettyflowers.jpg
1231509876 \USERS\HOMERSIMPSON\Doh.wav
1234567890 \TEMP\ANIMALS\DOGS\FILE1.pdf
0987654321 \TEMP\TREES\I hate willows.docx
1029383321 \COVID\CANSUCk\MYBALLS\prettyflowers.jpg

You get the picture. If I ECHO the IF "%%b"=="%%j" SET flag=1 I can clearly see in instances that they are equal, yet flag still shows as not defined.

So basically if the file names match I want to process that data a certain way.

2

1 Answer

•| Edit: This will prevent the remaining lines from going through the 2nd for loop when the flag has been set, and the line identities have already occurred.

As the flag has already been set, the loop does not need to continue.

If there are few lines, nothing changes, but if you have many lines, this can make a big difference in the total time process.

When adding the goto :skip, you goto exit the 2nd forcloop immediately, avoiding repetitive processing for each line, because you already been found the same string/line match.

@echo off && setlocal enabledelayedexpansion
cd /d "%~dp0" && if NOT exist NoMatchB.txt call :^)
for /f "tokens=1*" %%a in (NoMatchA.txt) DO ( SET "FLAG=" for /f "tokens=1*" %%i in (NoMatchB.txt)do if NOT defined flag ( IF /i "%%~b"=="%%~j" ( SET "flag=1" goto :skip ) ) :skip ECHO\value FLAG==!flag! IF DEFINED flag (ECHO\echoed FLAG==1) ELSE ECHO\echoed FLAG==Undefined? ECHO\ )
endlocal && goto :EOF

This is some that I prefer deal using with some different method.

You start the first loop by removing a variable, from there, it will only exist when some value is equal to "%%~b" and "%%~j".

After that point, there is no need to compare any values ​​within "%%~b" and "%%~j" in your 2nd loop.

Use if /i and ~ ("%%~b") to remove double quotes from the string and compare the two variables in the loop with "double quotes"

@echo off && setlocal enabledelayedexpansion
cd /d "%~dp0" && if NOT exist NoMatchB.txt call :^)
for /f "tokens=1*" %%a in (NoMatchA.txt) DO ( SET "FLAG=" for /f "tokens=1*" %%i in (NoMatchB.txt)do if NOT defined flag ( IF /i "%%~b"=="%%~j" SET "flag=1" ) ECHO\value FLAG==!flag! IF DEFINED flag (ECHO\echoed FLAG==1) ELSE ECHO\echoed FLAG==Undefined? ECHO\ )
endlocal && goto :EOF
:^)
>NoMatchA.txt ( echo;1231509876 \USERS\HOMERSIMPSON\Doh.wav echo;1234567890 \TEMP\ANIMALS\DOGS\FILE1.pdf echo;0987654321 \TEMP\TREES\I hate willows.docx echo;1029383321 \COVID\CANSUCk\MYBALLS\prettyflowers.jpg echo;9999999999 \COVID\CANSUCk\MYBALLS\FlowersOnly.jpg ) && (
>NoMatchB.txt ( echo;1234567890 \TEMP\ANIMALS\DOGS\FILE1.pdf echo;0987654321 \TEMP\TREES\I hate willows.docx echo;1122334455 \TEMP\LINUX ISOS\linustarvolds.iso echo;1029384756 \COVID\CANSUCk\MYBALLS\prettyflowers.jpg echo;9999999999 \COVID\CANSUCk\MYBALLS\OnlyFlowers.jpg ) ) && exit /b

If I'm wrong or not, not sure, but this work for me, see the results:

value FLAG==
echoed FLAG==Undefined?
value FLAG==1
echoed FLAG==1
value FLAG==1
echoed FLAG==1
value FLAG==1
echoed FLAG==1
value FLAG==
echoed FLAG==Undefined?
  1. In all loops pass in your 1st loop, you remove the variable flag:
set "flag="
  1. In first for loop remove the variable flag, in your 2nd for, you first check if your flag is not yet defined, if true, compare your variable %%~b and then set your flag variable to value 1:
 if not defined flag IF /i "%%~b"=="%%~j" SET "flag=1"
  1. Refer edit after setting its variable flag, because %%~b == %%~j, there is no need to continue comparing with the remaining lines of the file in this 2nd loop, then just use a goto :label to exit the loop immediately and continue the main loop.
 IF /i "%%~b"=="%%~j" ( SET "flag=1" Goto :skip ) ) :skip

2

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like