0

For the purpose of running a batch file that would search within all folders that live in R:\ except for those in exculde_dir.txt and then delete all files that do not match extensions in exclude_FILE.txt

I've been referring to a working answer,

Iterate all files in a directory using a 'for' loop Slightly modified, below:

for %%f in (R:\*) do ( something_here ^| findstr /I /V /L /G:"R:\exclude_FILE.txt")

in conjunction with another answer:

Windows 'findstr' command: Exclude results containing particular string

for /F "delims=" %%D in ('dir /B /S /A:D "R:" ^| findstr /I /V /L /G:"R:\exclude_DIR.txt"') do echo/%%D

Consider the following theoretical structure:

R:\DIR1\file.jpg
R:\DIR1\file.mkv
R:\DIR1\file.txt

R:\DIR2\file.jpg
R:\DIR2\file.mkv
R:\DIR2\file.txt

R:\DIR3\file.jpg
R:\DIR3\file.mkv
R:\DIR3\file.txt

R:\$RECYCLE.BIN

where the contents of the file exclude_FILE.txt

.mkv
.avi
.m4v

and exculde_DIR.txt

$RECYCLE.BIN
DIR2

but failing to get the syntax right. I'd expect only .mkv files to remain in DIR1 and DIR3, and any other directory not excluded, and the excluded DIR2 and recycle bin to be untouched. Thanks!

parsecpython
  • 585
  • 2
  • 6
  • 17
  • You may also wish to look at `RoboCopy` with its `/Move|/Mov`, and `/XD` and `/XF` options. Given just a handful of each, it may be a better tool for your job. You can find out more about the command, by entering, `robocopy /?` and reading the output. Among that the `/L` option may be useful when testing your scenarios. – Compo May 07 '19 at 23:42

1 Answers1

0

Using the findstr command, there is no need to separate directories from files, you could specify them in a single exclusion file, say exclude.txt, using regular expressions (/R) rather than literal strings (/L), and which might look like this (the # and everything behind is not part of the file content; ensure that there are no trailing white-spaces):

\\DIR2\\           # directory names in file paths must be given within literal `\`;
                   # this avoids partial directory names to match, like `myDIR2`, for instance;
\\$RECYCLE\.BIN\\  # literal `\` must be stated as `\\`, literal `.` as `\.`;
                   # also `[` and `]` needed to be escaped like `\[` and `\]`, respectively;
\.mkv$             # the trailing `$` symbol anchors the extension to the end of a file path;
\.avi$
\.m4v$

The suitable code for this is here:

rem // Note that the exclusion file must be placed in the same directory as this script!
for /F "delims=" %%I in ('
    dir /S /B /A:-D "R:\*.*" ^| findstr /I /R /V /G:"%~dp0exclude.txt"
') do (
    ECHO del "%%I"
)

After having tested the code, remove the upper-case ECHO command to actually delete files.

Perhaps it is a good idea to put the script and the exclusion file not in the target directory tree in order for them not to become deleted also. If you cannot guarantee that, you could extend the script so that it does these exclusions automatically on its own:

rem // Note that the exclusion file must be placed in the same directory as this script!
rem // Assign path the exclusion file to a variable:
set "EXCLUDE=%~dp0exclude.txt"
rem // Convert path of this script to a regular expression suitable for `findstr`:
call :CONVERT BATCH "%~f0"
rem // Convert path of exclusion file to a regular expression suitable for `findstr`:
call :CONVERT EXCLF "%EXCLUDE%"

for /F "delims=" %%I in ('
    dir /S /B /A:-D "R:\*.*" ^| ^
        findstr /I /R /V /G:"%EXCLUDE%" /C:"^%BATCH%$" /C:"^%EXCLF%$"
') do (
    ECHO del "%%I"
)
exit /B

:CONVERT
    rem // The first command line argument is a variable name;
    rem // Assign second command line argument to a variable:
    set "STR=%~2"
    rem // Escape certain characters that have special meaning to `findstr`:
    set "STR=%STR:\=\\%"
    set "STR=%STR:.=\.%"
    set "STR=%STR:[=\[%"
    set "STR=%STR:]=\]%"
    rem // Assign result to given variable:
    set "%~1=%STR%"
    exit /B
aschipfl
  • 33,626
  • 12
  • 54
  • 99