cmd – How to delete all files and folders in a directory respectively an entire directory tree except files specified in a list file?

Let us assume the list file G:ADmodsExclusion List.txt contains only file/folder names without path like:

Cleanup.cmd
Exclusion List.txt
Folder to keep
File not to delete.txt

The batch file G:ADmodsCleanup.cmd can be used with the following command lines to delete all files and folders in directory of the batch file with exception of the files and folders in exclusion list file:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FolderPath=%~dp0"
for /F "eol=| delims=" %%I in ('dir "%FolderPath%" /AD /B 2^>nul ^| %SystemRoot%System32findstr.exe /I /L /V /X /G:"%FolderPath%Exclusion List.txt"') do rd /Q /S "%FolderPath%%%I"
for /F "eol=| delims=" %%I in ('dir "%FolderPath%" /A-D /B 2^>nul ^| %SystemRoot%System32findstr.exe /I /L /V /X /G:"%FolderPath%Exclusion List.txt"') do del /A /F "%FolderPath%%%I"
endlocal

The first FOR Command line runs with using a separate command process started in background the command DI to output all folder names in directory of the batch file filtered with FINDSTR to exclude from the folder names list all folder names listed in the exclusion list file. The resulting list is processed by FOR which runs command RD to delete these folders.

The second FOR Command line runs with using a separate command process started in background the command DI to output all file names in directory of the batch file filtered with FINDSTR to exclude from the file names list all file names listed in the exclusion list file. The resulting list is processed by FOR which runs command DELE to delete these files.

The FOR option eol=| is used to avoid ignoring file/folder names starting with a semicolon as no file/folder name can contain a vertical bar. The FOR option delims= defines an empty list of string delimiters resulting in turning off the default behavior of for /F to split the captured lines into substrings (tokens) using normal space and horizontal tab as string delimiters and assign only the first space/tab separated string to the specified loop variable I. That option is necessary to correct process also file/folder names with one or more spaces.


The task requirements changed to delete all files in the entire directory tree except the files listed in an exclusion list file with path (without drive letter and colon).

So let us assume the file G:ADmodsExclusion List.txt contains the following lines.

G:ADmodsCleanup.cmd
G:ADmodsExclusion List.txt
ADmodsfolder1doc1.txt
ADmodsfolder1subfolder1doc1.txt
ADmodsfolder2doc1.txt

The batch file G:ADmodsCleanup.cmd can be used with the following command lines to delete first all files in the entire directory tree of the directory containing the batch file and the exclusion list file with exception of the files in the exclusion list file and next delete all directories recursively which do not contain anymore at least one file.

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "FolderPath=%~dp0"
if "%FolderPath:~-1%" == "" set "FolderPath=%FolderPath:~0,-1%"
for /F "delims=" %%I in ('dir "%FolderPath%" /A-D /B /S 2^>nul ^| %SystemRoot%System32findstr.exe /E /I /L /V /G:"%FolderPath%Exclusion List.txt"') do del /A /F "%%I"
call :DeleteEmptyFolders "%FolderPath%"
goto EndBatch

:DeleteEmptyFolders
for /F "eol=| delims=" %%I in ('dir %1 /AD /B 2^>nul') do call :DeleteEmptyFolders "%~1%%I"
for /F "eol=| delims=" %%I in ('dir %1 /A /B 2^>nul') do goto :EOF
rd /Q /S %1
goto :EOF

:EndBatch
endlocal

Please note that the FINDSTR option /X is replaced in first FOR command line by the option /E to filter out all file names of which full qualified name just ends with one of the strings in the exclusion list file instead of matching the entire file name because of the list file contains the file names without drive letter and colon. That could result in a wrong filtering depending on which part of the full path of a file is in the list file.

So what happens with this batch file on the following directory tree on drive G::

  • AD
    • backups
      • folder1
        • subfolder1
          • ;File to keep.txt
          • doc1.txt
        • doc1.txt
    • mods
      • folder1
        • subfolder1
          • ;File to delete.txt
          • doc1.txt
        • doc1.txt
        • One More File!.txt
      • folder2
        • Empty subfolder 1
        • Subfolder 2
          • Another Empty Folder
          • doc1.txt
        • doc1.txt
        • Log file in folder2().log
      • folder3
      • Cleanup.cmd
      • Exclusion List.txt
      • Readme.txt

The result of the execution of G:ADmodsCleanup.cmd is:

  • AD
    • backups
      • folder1
        • subfolder1
          • ;File to keep.txt
          • doc1.txt
        • doc1.txt
    • mods
      • folder1
      • folder2
      • Cleanup.cmd
      • Exclusion List.txt

So everything in G:ADbackups is kept and in G:ADmods Only the folders with files of which names are listed in the exclusion list file remain and all other files and folders are deleted by the batch script.

The directories and files can be created with the following batch code with exception of Cleanup.cmd and Exclusion List.txt in G:ADmods:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BasePath=G:"
md "%BasePath%ADbackupsfolder1subfolder1" 2>nul
md "%BasePath%ADmodsfolder1subfolder1" 2>nul
md "%BasePath%ADmodsfolder2Empty subfolder 1" 2>nul
md "%BasePath%ADmodsfolder2Subfolder 2Another Empty Folder" 2>nul
md "%BasePath%ADmodsfolder3" 2>nul
setlocal EnableDelayedExpansion
echo !BasePath!ADbackupsfolder1subfolder1;File to keep.txt>"!BasePath!ADbackupsfolder1subfolder1;File to keep.txt"
echo !BasePath!ADbackupsfolder1subfolder1doc1.txt>"!BasePath!ADbackupsfolder1subfolder1doc1.txt"
echo !BasePath!ADbackupsfolder1doc1.txt>"!BasePath!ADbackupsfolder1doc1.txt"
(echo !BasePath!ADmodsfolder1subfolder1;File to delete.txt>"!BasePath!ADmodsfolder1subfolder1;File to delete.txt") 2>nul
echo !BasePath!ADmodsfolder1subfolder1doc1.txt>"!BasePath!ADmodsfolder1subfolder1doc1.txt"
echo !BasePath!ADmodsfolder1doc1.txt>"!BasePath!ADmodsfolder1doc1.txt"
echo !BasePath!ADmodsfolder1One More File^^!.txt>"!BasePath!ADmodsfolder1One More File^!.txt"
(echo !BasePath!ADmodsfolder2Subfolder 2doc1.txt>"!BasePath!ADmodsfolder2Subfolder 2doc1.txt") 2>nul
echo !BasePath!ADmodsfolder2doc1.txt>"!BasePath!ADmodsfolder2doc1.txt"
echo !BasePath!ADmodsfolder2Log file in folder2().log>"!BasePath!ADmodsfolder2Log file in folder2().log"
echo !BasePath!ADmodsfolder3doc1.txt>"!BasePath!ADmodsfolder3doc1.txt"
echo !BasePath!ADmodsReadme.txt>"!BasePath!ADmodsReadme.txt"
endlocal
%SystemRoot%System32attrib.exe +r "%BasePath%ADmodsfolder1subfolder1;File to delete.txt"
%SystemRoot%System32attrib.exe +h "%BasePath%ADmodsfolder2Subfolder 2doc1.txt"
%SystemRoot%System32attrib.exe +h "%BasePath%ADmodsfolder2Empty subfolder 1"
%SystemRoot%System32attrib.exe +r +s +h "%BasePath%ADmodsfolder3"
endlocal

The deletion of the folder G:ADmodsfolder3 is tricky as it has the read-only attribute set (and the system and hidden attribute) which results in the error message Access is denied. on using the command rd %1 2>nul after the first FOR loop in subroutine DeleteEmptyFolders which would otherwise delete only empty folders. For that reason a second FOR loop is used running once again DI in a separate command process in background. The subroutine is exited if the directory is not empty because of still containing a file or a folder. Otherwise the folder is empty and rd /Q /S %1 is used to delete the empty folder even on having the read-only attribute set.


For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.

  • call /? … explains also %~dp0 … drive and path of argument 0 which is the batch file path always ending with a backslash.
  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • findstr /?
  • for /?
  • goto /?
  • if /?
  • rd /?
  • setlocal /?

Read the Microsoft documentation about Using command redirection operators for an explanation of 2>nul and |. The redirection operators > and | must be escaped with caret character ^ on the FOR Command lines to be interpreted as literal characters when Windows command interpreter processes the command line before executing command FOR which executes the embedded dir command line with findstr with using a separate command process started in background with %ComSpec% /c and the embedded command line appended as additional arguments.

Leave a Comment