guo
guo

Reputation: 293

delete some files in a sub-subfolder using batch script

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

Answers (2)

MC ND
MC ND

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

Infinite Recursion
Infinite Recursion

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.

Batch-file:

@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

Related Questions