Batch file ignores ELSE statement inside a FOR loop
I am currently creating a batch file that decompresses all the archives that it will detect in a specified folder. Right now I am trying to detect archive files within the specified folder using this code: #ECHO OFF SETLOCAL SETLOCAL EnableDelayedExpansion SET quote=" SET cwdText=Current working directory: SET cwd=%cd% SET fullCWD=%cwdText%%cwd% SET path=%~dp0 SET types=file_types.txt SET fullPath=%path%%types% ECHO %fullCWD% ECHO %fullPath% :SPECIFYPATH ECHO: SET /P directory=Specify the full path location of the archive files: IF "%cd%"=="%directory%" ( ECHO Specified location is already the current directory GOTO SPECIFYPATH ) ELSE ( PUSHD %directory% CD GOTO CHECKARCHIVES ) :CHECKARCHIVES FOR %%T IN (*.zip,*.rar,*.7z) DO ( IF EXIST %%T ( ECHO Archive files detected GOTO EOF ) ELSE ( ECHO Archive files not detected GOTO EOF ) GOTO EOF ) :EXTRACT ECHO Extracting archive files :EOF PAUSE The part wherein I start checking for archive files is at the :CHECKARCHIVES label. The problem I'm having right now is that whenever I try to specify a folder wherein there are no archive files, the code immediately jumps to the :EXTRACT label and does not go to the ELSE statement inside the FOR statement. Can someone explain why is that so? I also tried using IF NOT EXIST... statement just after the first IF statement but I still get the same behavior.
When the element that is being enumerated by the for command doesn't contain a wildcard, the code in the do clause is executed and the for replaceable parameter will contain the element as is. But when the element being enumerated contains a wildcard it is assumed that it needs to be expanded and the file system is checked for presence of files matching the wildcard expression. If there are not files matching, the code in the do clause will not be executed for this element. If there are files matching the expression, the code in the do clause will be executed not for the expression, but for each matching file, and the for replaceable parameter will hold a reference to the current one. As your code is using wildcards if there are matching files, the code in the do clause is executed for each of the files (in your case only for the first file found because the goto), and, if there are not any matching file, the code in the do clause is not executed so the else clause can not be reached. But, lets suppose that the for will not check the file system, and the elements indicated are iterated as written. You will have a logic error. The inner if command will check the existence of files matching only the first set. If not files matching the first set are found, you are leaving the for command with the goto inside the else clause, so, the rest of the sets are not checked. To keep the for to check for existence of files a better way could be for %%T in (*.zip, *.rar, *.7z) do goto :extract echo No archives found goto eof If any file, matching any of the wildcard expressions, is found then the goto will cancel the current enumeration and jump to your :extract label. If the for loop ends and the next line is reached it is because no matching file has been found.
That is the correct behavior for the code you have shown. If there are no archive file you will not enter the 'DO' construct. You could do something like this, or better yet zero a counter before entering the loop and increment it in the loop... then interrogate it outside the loop if you want a count of files. SET "Msg=Archive files not detected" FOR %%T IN (*.zip,*.rar,*.7z) DO ( SET "Msg=Archive files detected" REM do something else as needed ) ECHO %Msg%
In addition of RGuggisberg's post, you could check file like this with different syntax always outside the for-loop. for %%t in (*.zip,*.rar,*.7z) do set "myvar=%%t" if defined myvar ( echo msg#1 Archive files DETECTED ) else ( echo msg#1 Archive files NOT detected ) for %%t in (*.zip,*.rar,*.7z) do ( set "myvar=%%t" ) if defined myvar ( echo msg#2 Archive files DETECTED ) else ( echo msg#2 Archive files NOT detected ) rem check the myvar by negation if NOT defined myvar ( echo msg#3 Archive files NOT detected ) else ( echo msg#3 Archive files DETECTED )
Finding Strings on the text file - Batch file
How to set a program to run on startup depending on the time of day when the computer is turned on?
How to resolve “Gradle project failed” in Android Studio 2.2?
Android SDK could not be found - Android SDK Location is correct
How to detect which screen is the OSVR headset?
Phonegap Build, Adding a publisher id for windows
How can you identify a file without a filename or filepath?
Windows Batch, passing arguments with spaces
Docker can't pull image from repository
Vim: Split one file into multiple files based on row count
Can I check if a Windows process is running from a Google Chrome extension?
How can I push/fetch a git repository over a Bluetooth connection?
Changing desktop background by changing registry
TCP sockets on Windows UWP application
Windows Shell Script to scan folder & copy file
How to resolve 'unknown error: cannot find Chrome binary' once upgrading to chromedriver 2.25