Search code examples
batch-filefor-loopfindbatch-processingdir

How to exclude a directory from a dir call loop--faster than |find /v


Right now I've got a batch script that is used to go through a bunch of subfolders, and zip up the logfiles therein, the folder structure is basically like this:

+---fakeG
|   +---ExclusionFolder
|   |   +---LimitlessFolders
|   |   +---MoreFolders
|   |   \---SoManyFolders
|   +---logs1
|   +---logs2
|   +---logs3
|   +---logs4
|   +---logs5
|   \---logs6

Each of these subfolders must be traversed, and their subfolders traversed as well. This script has to avoid one specific folder, and it does avoid it, but it uses %| find /v. Although in this example, ExclusionFolder is at the top of the list, in the real folder structure it is not.

Here is how I do it now:

FOR /F "delims=" %%A IN (
    'DIR "%LogsFilespec%" /B /S ^| find /v "ExclusionFolder"'
) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog%

Inside ExclusionFolder, there are more subfolders, with potentially many more subfolders, so it would slow down the scripts execution having to go into each of them.

SO: Is there a faster way to exclude a folder from a dir call without |find ?

Or do I have to come up with a totally different way to do this?

Edit Sorry, %LogsFileSpec℅ refers to the target file. My original edit was right, and my second edit was wrong.

SET LogsLocation="G:\fakeG\Data\Logs"
SET LogsName="trace*%targetDate%.log"
SET LogsFilespec="%LogsLocation%\%LogsName%"

Sorry for not giving more of the script, I figured the question didn't need much.

Edit2 The process :DoZip works like this:

:DoZip
:: Parameter 1 = Filename without .EXT for Archive Name
:: Parameter 2 = Target file specifics
:: Parameter 3 = Zip Command (Winzip/7zip64/7zip32)
:: Parameter 4 = Zip Parameters (a -tzip, -a)
:: Parameter 5 = ProcessLog
setlocal 
SET archiveName=%~1
SET SourceFileSpec=%~2
SET zipCommand=%~3
SET zipParms=%~4
SET RunLog=%~5

    ECHO %TIME% Archiving %SourceFileSpec%...
    ECHO %TIME% Archiving %SourceFileSpec%... >> %RunLog%

    ECHO "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%"
    ECHO "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" >> %RunLog%
    "%zipCommand%" %zipParms% "%archiveName%.zip" "%SourceFileSpec%" >> %RunLog%

 :: Check errorlevel of executed command
 :: If errorlevel != 0, set EC with the errorlevel and echo that there was an error in archival
 IF NOT %ERRORLEVEL%==0 (
    ECHO ***ERROR archiving %SourceFileSpec% >>                                                                         %RunLog%
    SET EC=%ERRORLEVEL%
    ECHO ***ERRORLEVEL RETURNED: %EC% >> %RunLog%
) ELSE (
 :: Otherwise, delete the file
    ECHO. >>                                                                                                                            %RunLog%
    ECHO. >>                                                                                                                            %RunLog%
    ECHO %TIME% Deleting %SourceFileSpec%...
    ECHO %TIME% Deleting %SourceFileSpec%... >>                                                                         %RunLog%
 ::Quietly delete the file
    DEL /Q %SourceFileSpec%

    :: Set ErrorLevel to capture the Delete command result.
    SET EC=%ERRORLEVEL%
)
GOTO :EOF

Edit 3 Here is zipCommand

SET PathWinZip=C:\Program Files\WinZip\wzzip.exe
SET Path7Zip_64bit=C:\Program Files\7-Zip\7z.exe
SET Path7Zip_32bit=C:\Program Files (x86)\7-Zip\7z.exe

:: Check for WinZip
IF EXIST "%PathWinZip%" SET zipCommand=%PathWinZip% & SET zipParms=-a 

:: Check for 32-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST "%Path7Zip_32bit%" SET zipCommand=%Path7Zip_32bit% & SET zipParms=a -tzip

:: Check for 64-bit version of 7-Zip. If found, configure
:: its command line parameter to produce a .zip file
IF EXIST "%Path7Zip_64bit%" SET zipCommand=%Path7Zip_64bit% & SET zipParms=a -tzip

Solution

  • I believe that the following should exclude the subtree in question:

    FOR /F "delims=" %%X IN (
        'DIR /B /ad ') DO IF /i "%%X" neq "ExclusionFolder" FOR /F "delims=" %%A IN (
        'DIR  /B /S "%%X\%LogsFilespec%"'
    ) DO CALL :DoZip "%%~dpnA" "%%~fA" "%zipCommand%" "%zipParams%" %ProcessLog%
    

    That is, perform a directory-name scan of the target; if the directory found is not the exclude-name, then do the remainder for that subdirectory.