I am wondering how I can solve the following with a batch file.
Delete all files and folders inside G:\AD\mods
except for a list of all files and folders I want to keep.
Has anyone some suggestions for a batch file solution?
I have tried the following Windows command line in a batch file:
for %%i in (*.*) do if not "%%i"=="doc1.txt" if not "%%i"=="doc2.txt" del /q "%%i"
This works, but I was only able to delete files from the same folder as the batch file was placed in.
Then I read this post: Delete all files in folder except file in list using batch
It suggests something like:
except 3.txt del temp /Q
This also works in the same folder, but not for files and folders in different levels of the directory tree.
EDIT:
I have a main folder with about 1000 sub folders. These folders also have sub folders in them. The same file name might be present in multiple folders. So I need to specify the exact file path for each file I want to keep.
Example for the names in the list file of the files to keep:
AD\mods\folder1\doc1.txt
AD\mods\folder1\subfolder1\doc1.txt
AD\mods\folder2\doc1.txt
All other files should be removed by the batch file.
A PowerShell solution would be also okay.
CodePudding user response:
Let us assume the list file G:\AD\mods\Exclusion 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:\AD\mods\Cleanup.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%\System32\findstr.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%\System32\findstr.exe /I /L /V /X /G:"%FolderPath%Exclusion List.txt"') do del /A /F "%FolderPath%%%I"
endlocal
The first FOR command line runs in a separate command process started in background the command DIR 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 in a separate command process started in background the command DIR 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 DEL 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 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:\AD\mods\Exclusion List.txt
contains the following lines.
G:\AD\mods\Cleanup.cmd
G:\AD\mods\Exclusion List.txt
AD\mods\folder1\doc1.txt
AD\mods\folder1\subfolder1\doc1.txt
AD\mods\folder2\doc1.txt
The batch file G:\AD\mods\Cleanup.cmd
can be used with the following command lines to delete first all files in 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%\System32\findstr.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 following directory tree on drive G:
:
- AD
- backups
- folder1
- subfolder1
- ;File to keep.txt
- doc1.txt
- doc1.txt
- subfolder1
- folder1
- mods
- folder1
- subfolder1
- ;File to delete.txt
- doc1.txt
- doc1.txt
- One More File!.txt
- subfolder1
- folder2
- Empty subfolder 1
- Subfolder 2
- Another Empty Folder
- doc1.txt
- doc1.txt
- Log file in folder2().log
- folder3
- doc1.txt
- Cleanup.cmd
- Exclusion List.txt
- Readme.txt
- folder1
- backups
The result of the execution of G:\AD\mods\Cleanup.cmd
is:
- AD
- backups
- folder1
- subfolder1
- ;File to keep.txt
- doc1.txt
- doc1.txt
- subfolder1
- folder1
- mods
- folder1
- subfolder1
- doc1.txt
- doc1.txt
- subfolder1
- folder2
- doc1.txt
- Cleanup.cmd
- Exclusion List.txt
- folder1
- backups
So everything in G:\AD\backups
is kept and in G:\AD\mods
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 following batch code with exception of Cleanup.cmd
and Exclusion List.txt
in G:\AD\mods
:
@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "BasePath=G:"
md "