Home > other >  If a file was found more than once in subfolders - delete all using batch script
If a file was found more than once in subfolders - delete all using batch script

Time:09-17

The system I'm working on looks like this:

D:\TargetFolder\Subfolder1 
D:\TargetFolder\Subfolder2\Subfolder3

There is a file called "Settings.txt" that could exist in each of these folders. what I want is the following:

  • If the file was found more than once in the targeted folder and all of its subfolders then delete all of them.

  • If the file was found just once in the targeted folder and all of its subfolders then continue on with the script.

  • If the file doesn't exist then continue on with the script.

The final script could possibly be something like this:

IF exist "D:\TargetFolder\*Settings.txt" (goto delete) else goto continue
:delete
del *Settings.txt /f /q
:continue
exit

I hope I explained my question correctly. Thanks in advance.

CodePudding user response:

@echo off

for /F "skip=1" %%a in ('dir /B /S D:\TargetFolder\Settings.txt 2^>NUL') do (
   del /Q /S D:\TargetFolder\Settings.txt >NUL
   goto break
)
:break

The for /F loop process file names from dir /S command, but the first one is skipped (because "skip=1"switch), that is to say, if there are more than one file, the next commands are executed.

The first command in the for deletes all files with "Settings.txt" name and the for is break because the goto command.

CodePudding user response:

This batch file could be used for the task:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SettingsFile="
for /F "delims=" %%I in ('dir "D:\TargetFolder\Settings.txt" /A-D-L /B /S 2^>nul') do if not defined SettingsFile (set "SettingsFile=1") else (del "D:\TargetFolder\Settings.txt" /A /F /Q /S >nul 2>nul & goto Continue)
:Continue
endlocal

A less compact variant of above:

@echo off
setlocal EnableExtensions DisableDelayedExpansion
set "SettingsFile="
for /F "delims=" %%I in ('dir "D:\TargetFolder\Settings.txt" /A-D-L /B /S 2^>nul') do (
    if not defined SettingsFile (
        set "SettingsFile=1"
    ) else (
        del "D:\TargetFolder\Settings.txt" /A /F /Q /S >nul 2>nul
        goto Continue
    )
)
:Continue
endlocal

First, there is made sure that the environment variable SettingsFile is not defined by chance.

Next the command DIR is executed by a separate command process started in background to search in D:\TargetFolder for files with name Settings.txt and output them all with full path. The output of DIR is captured by FOR and processed line by line if DIR found the file Settings.txt at all.

The environment variable SettingsFile is defined with a string value which does not really matter on first file Settings.txt. The FOR loop finishes without having done anything else if there is no more file Settings.txt.

But on second file Settings.txt is executed the command DEL to delete in the specified folder and all its subfolders the file Settings.txt. The loop is excited with command GOTO to continue batch file processing on the line below label Continue as the other occurrences of Settings.txt do not matter anymore and of course do not exist anymore on deletion of all Settings.txt was successful.

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.

  • del /?
  • dir /?
  • echo /?
  • endlocal /?
  • for /?
  • goto /?
  • if /?
  • set /?
  • setlocal /?

Read the Microsoft documentation about Using command redirection operators for an explanation of >nul and 2>nul. The redirection operator > must be escaped with caret character ^ on FOR command line to be interpreted as literal character when Windows command interpreter processes this command line before executing command FOR which executes the embedded dir command line in a separate command process started in background with cmd.exe /c and the command line within ' appended as additional arguments.

See also single line with multiple commands using Windows batch file for an explanation of operator &.

CodePudding user response:

This is not difficult if you can use the PowerShell already on your Windows system. If the count of files found is greater than zero, then each one is deleted. Otherwise, nothing happens. When you are confident that the correct files will be deleted, remove the -WhatIf from the Remove-Item command.

@powershell.exe -NoLogo -NoProfile -Command ^
    "$Files = Get-ChildItem -Recurse -File -Path 'C:\TargetFolder' -Filter 'Settings.txt';" ^
    "if ($Files.Count -gt 1) {" ^
        "foreach ($File in $Files) { Remove-Item $File.FullName -Whatif }" ^
    "}"

Some of the noise can be eliminated if it could be run as a PowerShell .ps1 script file.

$Files = Get-ChildItem -Recurse -File -Path 'C:\TargetFolder' -Filter 'Settings.txt'
if ($Files.Count -gt 1) {
    foreach ($File in $Files) { Remove-Item $File.FullName -Whatif }
}
  • Related