Reputation: 293
I need a batch script that deletes all files from a sub-subfolder of a given folder except two files.
I have a set of the name of the subfolders where the files can be found set sf=(sf0 sf1)
These subfolders are nested somewhere below a given path, e.g.
<givenPath>\something\anything\sf0
<givenPath>\whatever\sf1
In those subfolder I like now to delete all files except 2.
All other files and subfolders in <givenPath>
have to remain untouched.
I figured out this could be achieved with something like:
for /R "%somePath%" %%D in (*.*) do (
if /I not "%%D"=="dontDelete.file" (
if /I not "%%D"=="hasToStay.file" (
echo del /S /Q "%somePath%\%%D"
)
)
)
My problem is now to get %some_path%
to point to the correct subfolder as explained above.
How could this be achieved? Or am I completely wrong and there is a better approach?
Upvotes: 0
Views: 904
Reputation: 70923
This will do the work in two steps
First, a full list of folders (under the given path) is generated. This list of folders is filtered to not contain the "special" folders. For the rest of the folders, all the files are deleted.
Next, all the remaining files are enumerated (that is the reason for the first step, if it is not necessary do not deal with files, just folders, so this second list is shorter). This list is filtered to exclude any "special" file under the "special" folders. The remaining files are deleted.
@echo off
setlocal enableextensions disabledelayedexpansion
rem configure starting path
set "givenPath=%cd%"
rem list of folders that need a special test
set "specialFolders="sf0" "sf1""
rem list of files to keep inside special folders
set "specialFiles="dontDelete.file" "hasToStay.file""
rem a temporary file will be needed
set "tempFile=%temp%\%~nx0.%random%.tmp"
rem STEP 1 - remove all files from non special folders
rem prepare temporary file to filter the list of folders
(for %%a in (%specialFolders%) do echo \%%~a) > "%tempFile%"
rem remove all files from not special folders
for /f "delims=" %%a in ('
dir /ad /s /b "%givenPath%" ^| findstr /i /v /e /l /g:"%tempFile%"
') do echo del /f /q "%%~fa\*"
rem STEP 2 - Delete all non special files from special folders
rem generate a temporay file to filter the list of files
(for %%a in (%specialFolders%) do for %%b in (%specialFiles%) do echo \%%~a\%%~b) > "%tempFile%"
rem remove any file not matching the special folder/files
for /f "delims=" %%a in ('
dir /a-d /s /b "%givenPath%" ^| findstr /i /v /e /l /g:"%tempFile%"
') do echo del /f /q "%%~fa"
rem remove temporary file
del /q "%tempFile%" >nul
It is possible to remove the first step and the result will be the same, but instead of executing one del
operation for non special folders, there will be a del
operation for each of the files inside them.
Delete operations are only echoed to console. If the output is correct, remove the echo
that prefix the del
commands
This echo
command for testing makes the second step find all the files that has not been deleted (the echo
) in the first step. Without the echo
in the first step removed, the second step is faster as it has to deal with less files.
EDITED to adapt to comments - As only the non special files inside special folders should be deleted
@echo off
setlocal enableextensions disabledelayedexpansion
rem configure starting path
set "givenPath=%cd%"
rem list of folders that need a special test
set "specialFolders="sf0" "sf1""
rem list of files to keep inside special folders
set "specialFiles="dontDelete.file" "hasToStay.file""
rem temporary files will be needed
set "folderFilter=%temp%\%~nx0.%random%.1.tmp"
set "fileFilter=%temp%\%~nx0.%random%.2.tmp"
rem prepare temporary file to filter the list of folders
(for %%a in (%specialFolders%) do echo \\%%~a\\[^^\\]*) > "%folderFilter%"
rem prepare temporary file to filter the list of files
(for %%a in (%specialFiles%) do echo \%%~a) > "%fileFilter%"
rem Search all files, filter and delete
for /f "delims=" %%a in ('
dir /s /b /a-d "%givenPath%"
^| findstr /i /e /r /g:"%folderFilter%"
^| findstr /i /e /l /v /g:"%fileFilter%"
') do echo del /f /q "%%~fa"
rem remove temporary files
del /q "%folderFilter%" > nul
del /q "%fileFilter%" > nul
Retrieve the full list of files (dir /s
), remove from it anything not inside a special folder (findstr
with folderFilter), and from the remaining list of files, remove special files (findstr
with fileFilter). Anything still in the list is to be deleted
As in the previous code, the del
operations are only echoed to console. If the output is correct, remove the echo
to delete the files.
Upvotes: 0
Reputation: 6557
You can recursively search the filenames and delete the files.
I am not deleting the subdirectories as it is not clear from your question, if you want to keep the directories.
All the files from all the directories except two files "file1" and "file2" will be deleted, and the directories will stay. If you want to delete the directories, remove the first if-loop which keeps the directories.
@echo off
rem set your two file names in these variables
set file1="a.txt"
set file2="b.txt"
for /f "delims=" %%a in ('dir /s /b *.*') do (
if exist %%~sa\NUL (
echo It is a directory, not deleted: %%~sa
) else if "%%~nxa" == %file1% (
echo Not deleted : %file1%
) else if "%%~nxa" == %file2% (
echo Not deleted : %file2%
) else (
del /s /q "%%a"
)
)
Upvotes: 0