For Loop

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
eXoScoriae
Posts: 1
Joined: 19 Oct 2020 16:47

For Loop

#1 Post by eXoScoriae » 19 Oct 2020 17:00

This is likely fairly simple, but it is escaping me.

Usage:
This is an update file. It checks a folder full of zip files. For each zip file (FILENAME), it then checks an index file and determines what folder that zip file should update. Then, it sees if that folder exists, and unzips the zip file to that folder if it finds it. A prior process downloads updates, so the number of files in the update folder is variable and based on how many exist at the time the original update script is run.

Script:
@echo off
for %%f in (.\Update\!dos\*.zip) do set FileName3=%%f
set trim=.\Update\!dos\
CALL set FileName2=%%FileName3:%trim%=%%
set FileName=%FileName2:~0,-4%
for /F "delims=" %%a in ('findstr /C:"%FileName%" .\Update\index.txt') do set fullindex=%%a
set removeindex=%fullindex:*:=%
CALL set result=%%fullindex:%removeindex%=%%
set index=%result:~0,-1%
if exist .\Apps\%index% .\util\unzip -o ".\Update\!dos\%FileName2%" -d .\Apps\


The script is an update batch file.
Line 2 checks a folder for zip files. The idea is that each zip file represents a different update. And this process should be run for each zip file. Lets call each of these files FILENAME going forward.
Line 2 sets the zip file to a variable.
Line 3 sets a variable used in line 4 to trim out the leading folders. Now FileName2 is just the zip file name
Line 5 then trims the file extension. So now we have the file name without ".zip"
Line 6 compares the filename to a index.txt file. The format of this file is something like
FOLDERNAME:FILENAME
It finds the line that has a matching FILENAME and assigns it to %fullindex%
Line 7 sets a variable with the FILENAME
Line 8 trims that value from the %fullindex%. Essentially, now I have the FOLDERNAME: from the index, and it is assigned to %result%
Line 9 trims the : from this value, leaving just FOLDERNAME assigned to %index%
Now, after all that I know the FOLDERNAME that this FILENAME should unzip to. So it checks to see if that update needs to be installed. It does this by ensuring a folder of that name exists. If it does exist, it extracts the FILENAME.zip to that folder.

Now, to be clear, this entire process works great. One time. The first zip file it finds, it properly parses, checks the index, see's if the folder exists, and then extracts it. And then it exits. The idea is to make it continually loop for *each* file in the .\Update\!dos\ folder.

I tried putting the bulk of the script in parenthesis, following that for loop.
eg:
for %%f in (.\Update\!dos\*.zip) do (
set FileName3=%%f
set trim=.\Update\!dos\
CALL set FileName2=%%FileName3:%trim%=%%
set FileName=%FileName2:~0,-4%
for /F "delims=" %%a in ('findstr /C:"%FileName%" .\Update\index.txt') do set fullindex=%%a
set removeindex=%fullindex:*:=%
CALL set result=%%fullindex:%removeindex%=%%
set index=%result:~0,-1%
if exist .\Apps\%index% .\util\unzip -o ".\Update\!dos\%FileName2%" -d .\Apps\
)

However this causes syntax errors. FileName 3 never gets assigned properly when using this method. Which means all variables fail after this point.

So, the question is, how can I take the working script I have above, and make it loop for each file in the folder rather than only running once?

I hope I explained this properly. Thank you,

aGerman
Expert
Posts: 4654
Joined: 22 Jan 2010 18:01
Location: Germany

Re: For Loop

#2 Post by aGerman » 20 Oct 2020 14:04

Variables in a command line or a block of command lines enclosed in parentheses are expanded to their values once before the line/block is executed. The body of your outer loop is such a block. EnableDelayedExpansion would help. But since your folder name contains an exclamation point things would be more complicated. However, based on your explanation you don't even need all of these extra variables and string manipulations. The FOR variables support modifiers which are able to extract file name and/or extension out of the box. Also FOR /F is made to split strings on delimiters. So, your script could look like that in the end (of course not tested because neither do I have your zip files nor your index.txt):

Code: Select all

for %%f in (".\Update\!dos\*.zip") do (
  for /f "delims=:" %%a in ('findstr /C:"%%~NXf" ".\Update\index.txt"') do (
    if exist ".\Apps\%%a" .\util\unzip -o ".\Update\!dos\%%~Nf" -d ".\Apps\"
  )
)
Steffen

Post Reply