windows


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 )

Related Links

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

Categories

HOME
search
assembly
gridview
facebook-oauth
jmeter
angular-formly
themes
composite-primary-key
owl-carousel
nuget
dojo
emscripten
regular-language
categorical-data
reactive-programming
project-intu
jxl
angular-dart
jsonpath
azure-iot-hub
entitymanager
microsoft-dynamics-nav
breadth-first-search
ag
guzzle
string-concatenation
parcelable
flask-sqlalchemy
xunit
ckfinder
froala
ms-access-web-app
firebase-analytics
winexe
gp
google-cast
send
spring-security4
gnat-gps
html-encode
protege4
swagger-php
parse-tree
xdocreport
apns-php
railstutorial.org
demo
unordered-map
magento-1.9.3
angular-http
berkeley-db-je
phpdbg
ovf
proget
yii2-api
insight
static-cast
compiler-design
git-flow
headless
reachability
qtplugin
tinkerpop3
uicolor
mta
i386
qiime
deep
toast
sciruby
dllimport
rewrite
batik
bufferedinputstream
node-serialport
osc
rrule
cakephp-2.7
mmwormhole
openbabel
ssis-data-flow
rmysql
xml-dsig
tinyxml
authlogic
synapse
getopt
asdf
process-explorer
facebook-timeline
superscrollorama
qi4j
pstack
window-decoration
agility.js
ruby-1.8
build-environment
int64

Resources

Encrypt Message