How to delete empty folders using windows command prompt? - windows

I need to delete all empty folders from my application folder using windows command prompt?
How can I create a bat file like that?
Please help me.

You can use the ROBOCOPY command. It is very simple and can also be used to delete empty folders inside large hierarchy.
ROBOCOPY folder1 folder1 /S /MOVE
Here both source and destination are folder1, as you only need to delete empty folders, instead of moving other(required) files to different folder. /S option is to skip copying(moving - in the above case) empty folders. It is also faster as the files are moved inside the same drive.

A simpler way is to do xcopy to make a copy of the entire directory structure using /s switch. help for /s says Copies directories and subdirectories except empty ones.
xcopy dirA dirB /S
where dirA is source with Empty folders. DirB will be the copy without empty folders

for /f "usebackq" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
from: http://blogs.msdn.com/b/oldnewthing/archive/2008/04/17/8399914.aspx
Of course I'd test it first without deleting before I do that command. Also, here's a modded version from the comments that includes folders with spaces:
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"
P.S. there are more comments in the blog post that might help you out so be sure to read those too before you try this out

You don't need usebackq:
FOR /F delims^= %%A IN ('DIR/AD/B/S^|SORT/R') DO RD "%%A"

Adding to corroded answer from the same referenced page is a PowerShell version http://blogs.msdn.com/b/oldnewthing/archive/2008/04/17/8399914.aspx#8408736
Get-ChildItem -Recurse . | where { $_.PSISContainer -and #( $_ | Get-ChildItem ).Count -eq 0 } | Remove-Item
or, more tersely,
gci -R . | where { $_.PSISContainer -and #( $_ | gci ).Count -eq 0 } | ri
credit goes to the posting author

from the command line:
for /R /D %1 in (*) do rd "%1"
in a batch file
for /R /D %%1 in (*) do rd "%%1"
I don't know if it's documented as such, but it works in W2K, XP, and Win 7. And I don't know if it will always work, but it won't ever delete files by accident.

This is a hybird of the above. It removes ALL files older than X days and removes any empty folders for the given path. To use simply set the days, folderpath and drive
#echo off
SETLOCAL
set days=30
set folderpath=E:\TEST\
set drive=E:
::Delete files
forfiles -p %folderpath% -s -d -%days% -c "cmd /c del /q #path "
::Delete folders
cd %folderpath%
%drive%
for /f "usebackq delims=" %%d in (`"dir /ad/b/s | sort /R"`) do rd "%%d"`

It will be worked fine. This is best way to delete old files and remove empty directories recursively.
following .bat file is,
forfiles /p [PATH] /s /m [FILE-PATTERN] /d -[DAYS] /c "cmd /c del #path"
for /f "delims=" %%d in ('dir [PATH] /s /b /ad ^| sort /r') do rd "%%d"
The placeholders needs to be replaced as follows (without the quotation marks):
[DAYS] = Max. age of the files in days, e.g. “10”
[PATH] = Path to search for old files and empty folders, e.g. “C:\Backup\”
[FILE-PATTERN] = Pattern that matches files to delete, e.g. “*.bkp”
The script has been successfully tested under Windows 7 and Windows Server 2003.

Install any UNIX interpreter for windows (Cygwin or Git Bash) and run the cmd:
find /path/to/directory -empty -type d
To find them
find /path/to/directory -empty -type d -delete
To delete them
(not really using the windows cmd prompt but it's easy and took few seconds to run)

#echo off
set /p "ipa= ENTER FOLDER NAME TO DELETE> "
set ipad="%ipa%"
IF not EXIST %ipad% GOTO notfound
IF EXIST %ipad% GOTO found
:found
echo DONOT CLOSE THIS WINDOW
md ccooppyy
xcopy %ipad%\*.* ccooppyy /s > NUL
rd %ipad% /s /q
ren ccooppyy %ipad%
cls
echo SUCCESS, PRESS ANY KEY TO EXIT
pause > NUL
exit
:notfound
echo I COULDN'T FIND THE FOLDER %ipad%
pause
exit

If you want to use Varun's ROBOCOPY command line in the Explorer context menu (i.e. right-click) here is a Windows registry import. I tried adding this as a comment to his answer, but the inline markup wasn't feasible.
I've tested this on my own Windows 10 PC, but use at your own risk. It will open a new command prompt, run the command, and pause so you can see the output.
Copy into a new text file:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\Software\Classes\directory\Background\shell\Delete Empty Folders\command]
#="C:\Windows\System32\Cmd.exe /C \"C:\Windows\System32\Robocopy.exe \"%V\" \"%V\" /s /move\" && PAUSE"
[HKEY_CURRENT_USER\Software\Classes\directory\shell\Delete Empty Folders\command]
#="C:\Windows\System32\Cmd.exe /C \"C:\Windows\System32\Robocopy.exe \"%V\" \"%V\" /s /move\" && PAUSE"
Rename the .txt extension to .reg
Double click to import.

for /r "D:\Music" /d %F in (.) do #dir /b "%F" | findstr "^" >nul || rmdir %~fF
D:\Fun is the folder that contains empty folders
double quotation in the case of space in folder name (no need in this example)

A more modern and easier solution is:
forfiles /p C:\Path\To\Folder /c "cmd /c if #isdir==TRUE rd #file"
This will attempt to execute rd on all the directories located in C:\Path\To\Folder. Directories that have content in them will not be deleted.
If you exclude /p C:\Path\To\Folder then it'll run in the current directory.
If you add /s (before the /c) then it'll also look in sub-directories.

The following .cmd is an experiment (that works) to:
Deletes empty directories and included "Old"(-1days) files under %temp% & C:\Windows\Temp folders,
makes an cmd output log to a .txt file, about fouded & deleted folders/files .
%temp% = C:\Users(user)\AppData\Local\Temp | %userprofile%\AppData\Local\Temp
code:
:: This is a .cmd file
:: Use to:
:: Writes a Log about Temporary files & folders.
:: Cleans 'Windows Temp' folders/files. (%userprofile%\AppData\Local\Temp -&- %windir%\Temp)
:: - a 'Cleaning_LOGs.txt' will be created or updated in Documents Library. (%userprofile%\Documents\Cleaning_LOGs.txt)
::
#echo off
title Log&CleanTemp
: Set the Path of 'Log file' (%LogPath% variable)
set "LogPath=%userprofile%\Documents\Cleaning_LOGs.txt"
:: Note: ">> path\file.txt 2>&1" redirects cmd output to <path\to>\<log_file.txt>, (will be created if does not exist)
:: (if exist, adds the new log at the end of the file, without deleting previous logs)
: Set 'C:\Windows\Temp' (%WinTemp% var.)
set "WinTemp=%windir%\Temp"
: Seperator [Header] with Date-Time between (any) previous Logs in <log_file.txt>
echo: >> %LogPath% 2>&1
echo ======================================== >> %LogPath% 2>&1
echo %date% - %time% >> %LogPath% 2>&1
echo: >> %LogPath% 2>&1
echo Log Path: %LogPath% (this text file) >> %LogPath% 2>&1
echo: >> %LogPath% 2>&1
: Report Output & Log
:: Writes a log about temporary files & folders.
:: Note: ( %temp% = C:\Users\<user>\AppData\Local\Temp = %userprofile%\AppData\Local\Temp )
:: ( 'WinTemp' = C:\Windows\Temp = %windir%\Temp )
echo: >> %LogPath% 2>&1
echo __________ Empty (0 size) , Old (-1days) files: >> %LogPath% 2>&1
ForFiles /p "%temp%" /s /d -1 /c "cmd /c if #fsize==0 ECHO #path " >> "%LogPath%" 2>&1
ForFiles /p "%WinTemp%" /s /d -1 /c "cmd /c if #fsize==0 ECHO #path " >> "%LogPath%" 2>&1
echo: >> %LogPath% 2>&1
echo __________ All Old (-1days) files: >> %LogPath% 2>&1
ForFiles /p "%temp%" /s /d -1 /c "cmd /c ECHO #path " >> "%LogPath%" 2>&1
ForFiles /p "%WinTemp%" /s /d -1 /c "cmd /c ECHO #path " >> "%LogPath%" 2>&1
:: Note: "ForFiles" /p=Path /s=SubDir /d=Days(dd) /c=cmd "forfiles /?" for info about command's Variables (#path, #file, etc.)
: Get permissions (unlock files/folders) (OPTIONAL)
:: Uncomment to make it work, IF needed.
::echo: >> %LogPath% 2>&1
::ForFiles /p "%temp%" /s /d -1 /c "cmd /c TAKEOWN /f * /r /d y && ICACLS #file /grant *S-1-3-4:F /t /c /l /q"
: Clean proper files & Log it
:: Test: ForFiles /p "%temp%\" /s /d -1 /c "cmd /c if #fsize==0 DEL /f /s /q #file" >> "%LogPath%" 2>&1
:: ERROR: Invalid argument/option - '#fsize==0'
echo: >> %LogPath% 2>&1
echo __________ Deleted files: >> %LogPath% 2>&1
forfiles /p %temp%\ /s /d -1 /c "cmd /c DEL /f /s /q #path" >> "%LogPath%" 2>&1
forfiles /p %WinTemp%\ /s /d -1 /c "cmd /c DEL /f /s /q #path" >> "%LogPath%" 2>&1
echo: >> %LogPath% 2>&1
echo __________ Deleted empty directories: >> %LogPath% 2>&1
for /f "delims=" %%d in ('dir %temp%\ /s /b /ad ^| sort /r') do RD "%%d" >> "%LogPath%" 2>&1
for /f "delims=" %%d in ('dir %WinTemp%\ /s /b /ad ^| sort /r') do RD "%%d" >> "%LogPath%" 2>&1
:: Note: 'RD' = Remove-Directory (delete)
: Open Log file
:: this opens the log file [(my) Documents\Cleaning_LOGs.txt]
explorer.exe %LogPath%
:: https://stackoverflow.com/questions/7831286/how-to-delete-empty-folders-using-windows-command-prompt/46617314#46617314
Note that:
The trigger to Experiment with this, as part of a 'pre-process', was to prevent the specific (obsolete) driver of the (also obsolete) sound card from automatically reinstalling at each boot. And clean (ghosted) hidden Devices and more other. (...) (this note was just about to get an idea for the use)
So, in a few words:
This is the part that cleans up the 'temp' garbage left behind and gives a report.

well, just a quick and dirty suggestion for simple 1-level directory structure without spaces, [edit] and for directories containing only ONE type of files that I found useful (at some point from http://www.pcreview.co.uk/forums/can-check-if-folder-empty-bat-file-t1468868.html):
for /f %a in ('dir /ad/b') do if not exist %a\*.xml echo %a Empty
/ad : shows only directory entries
/b : use bare format (just names)
[edit] using plain asterisk to check for ANY file (%a\* above) won't work, thanks for correction
therefore, deleting would be:
for /f %a in ('dir /ad/b') do if not exist %a\*.xml rmdir %a

This can be easily done by using rd command with two parameters:
rd <folder> /Q /S
/Q - Quiet mode, do not ask if ok to remove a directory tree with
/S
/S - Removes all directories and files in the specified directory
in addition to the directory itself. Used to remove a directory tree.

Related

Windows Batch:Count the number of files deleted using forfiles command

I have written a simple batch job for copying the files from one folder to another that are older than x-number of days using forfiles. But I need to count the number of files that have been copied. I tried various ways to do this but was unsuccessful. Could any body help me trough this?
#Echo off
Echo Starting the script for copying files to other folder.
set dt=%date:~10,4%-%date:~4,2%-%date:~7,2%_%time:~0,2%%time:~3,2%%time:~6,2%
set filesMovedCount=0
forfiles /p C:\symphonybackup\symphonybackup\Symphony\SymphonyArcheive /s /m *.* /d -30 /c "cmd /c echo #path >> C:\symphonybackup\symphonybackup\Symphony\%dt%.log & cmd /c copy #path C:\symphonybackup\symphonybackup\Symphony\SymphonyTemp"
Echo filesmovedcount:%filesMovedCount%
Echo finised copying the files
You could just pipe all of your copied file names to a file and then count the rows in the file. Here I added the additional stuff, you can just add the commands where the output gets piped to logfile where indicated. When done, it will echo the count and you delete the file.
#echo off
forfiles /p "rest of copy commands" >>logfile.txt
setlocal EnableDelayedExpansion
set "string=findstr /R /N "^^" logfile.txt | find /C ":""
for /f %%a in ('!string!') do set count=%%a
echo %count% files copied
del /Q logfile.txt
Mayby late answer to this, but when I try this:
set "string=findstr /R /N "^^" logfile.txt | find /C ":""
for /f %%a in ('!string!') do set count=%%a
I get one extra result since I get one empty row. So I did need have to add -1 to the result.
Atleast on my system...

windows server 2008 r2 7z backup script

I am trying to get this script to backup a specific folder/files and zip them, then move the zip to a diff folder.
but i keep getting an error.
#ECHO off
SETLOCAL
ECHO + Setting up environment variables.
SET BACKPATH=%ThisService_RootDirectory%temp\
SET ARCPATH=C:\Program Files\7-Zip\7z.exe
SET ARCPARAMS=a -y
SET DAYSTOKEEP=3
SET ARCHIVE_DAYSTOKEEP=30
SET SOURCEPATH=%ThisService_RootDirectory%MPMissions
SET DEST_PATH=%ThisService_RootDirectory%Backups
SET BACKUP_DEST=%date:~-7,2%-%date:~4,2%-%date:~-4,4%
IF NOT EXIST "%BACKPATH%" (
ECHO ! Backup Path not found, exiting.
GOTO END
) ELSE (
ECHO * Backup Path Found.
)
IF NOT EXIST "%ARCPATH%" (
ECHO ! Archiver not found, exiting.
GOTO END
) ELSE (
ECHO * Archiver Found.
)
ECHO * Copying Files...
xcopy "%SOURCEPATH%\Documents" "%BACKPATH%\%BACKUP_DEST%\MPMissions" /v /e /s /i /y 1>NUL 2>NUL
ECHO * Archiving files...
CD /D "%BACKPATH%"
FOR /f %%a IN ('FORFILES /P %BACKPATH% /C "cmd /c if #isdir==TRUE echo #file" /D -%DAYSTOKEEP%') DO (
IF NOT EXIST %%a.7z (
"%ARCPATH%" %ARCPARAMS% %%a.7z %BACKPATH%\%%a\*.* 1>NUL 2>NUL
copy %%a.7z %DEST_PATH% 1>NUL 2>NUL
del %%a.7z 1>NUL 2>NUL
)
)
ECHO * Cleaning folders older than %DAYSTOKEEP% days..
FORFILES /P %BACKPATH% /C "cmd /c if #isdir==TRUE rmdir /s /q #file" /D -%DAYSTOKEEP% 1>NUL 2>NUL
ECHO * Cleaning files older than %DAYSTOKEEP% days..
FORFILES /P %BACKPATH% /M *.7z /C "cmd /c if #isdir==FALSE del #file" /D -%DAYSTOKEEP% 1>NUL 2>NUL
ECHO * Cleaning archives files older than %ARCHIVE_DAYSTOKEEP% days..
FORFILES /P %DEST_PATH% /M *.7z /C "cmd /c if #isdir==FALSE del #file" /D -%ARCHIVE_DAYSTOKEEP% 1>NUL 2>NUL
:END
ENDLOCAL
once I run the script it gives this message:
Setting up environment variables.
Backup Path Found.
Archiver Found.
Copying Files...
Archiving files...
ERROR: No files found with the specified search criteria.
Cleaning folders older than 3 days..
Cleaning files older than 3 days..
Cleaning archives files older than 30 days..
The script has executed successfully. You may close this window.
Now the variable %ThisService_RootDirectory% is part of tcadmin which is a gaming server service, so that variable where im executing the batch script would turn that variable into an actual path of the users service
example:
%ThisService_RootDirectory%
is
C:\TCAFiles\users\admin\5\
the script copies the files to the required folder, but it does not seem to zip the files and move the zip to the required folder.
can anyone give some assistance here please.
original source is at https://community.spiceworks.com/topic/482860-batch-script-to-transfer-and-compress
It's not a direct response to your question but why reinvent the wheel ?
All you need is in 7zBackup.ps1 (a powershell script which does exactly this)

forfiles in certain subfolder in multiple folders

Is there away to only display files in a folder called "Export", when such a subfolder is in multiple locations?
This will display all .xlsx files below where I'm running the batch file from, however I don't want to display all, I only want to display things in a folder called "Export":
forfiles -p "%~dp0\" -s -m *.xlsx -d -365 -c "cmd /c ECHO #relpath"
I have attempted things like:
forfiles -p "%~dp0\*\Export" -s -m *.xlsx -d -365 -c "cmd /c ECHO #relpath"
However it doesn't recognise syntax like this. Says invalid argument/option, but they are valid until I add *\ to the path.
This is an example of the structure I'm working with and what I what results to display:
%~dp0\1\Exports\Excel\ - (Do display .xlsx files)
%~dp0\1\Do Not Delete\Excel\ - (Don't display .xlsx files)
%~dp0\2\Exports\Excel\ - (Do display .xlsx files)
%~dp0\2\Do Not Delete\Excel\ - (Don't display .xlsx files)
The number folders would be a variable somehow, which is why the *\ is in my attempt.
I will then edit this to delete the files when I know it's picking up the right ones.
You could use two nested forfiles loops:
forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C echo 00x7840path0x22"
This command line walks through the given root directory (%~dp0) recursively and iterates through all items matching Export* (you might replace this pattern by Export or Exports, depending on your needs); the hierarchy depth is not checked in order to avoid the need of three nested loops. Anyway, if the iterated item is a directory, the sub-directory Excel is enumerated and searched for items matching *.xlsx.
Supplement:
The above command line may display many error messages like ERROR: The specified directory does not exist. or ERROR: Files of type "*.xlsx" not found., depending on your data; to avoid them, redirect STDERR to the nul device:
2> nul forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C echo 00x7840path0x22"
The forfiles command returns an empty line to STDOUT, so the above command line will contain many of them; to avoid such too, redirect STDERR and STDOUT to the nul device and redirect only the wished data to the console con:
1> nul 2>&1 forfiles /S /P "%~dp0\" /M "Export*" /C "cmd /C if #isdir==TRUE forfiles /P #path\Excel /M *.xlsx /D -365 /C 0x22cmd /C 1> con echo 00x7840path0x22"
You can send results with | to FINDSTR like this:
FORFILES /P . /S /M *.xlsx /D -365 /C "CMD /C ECHO #path" | ^
FINDSTR "\\Exports\\" | ^
FINDSTR /I /C:Delete /V
So you search every xlsx files located in a certain path (here is current dir) Every xlsx must contain Exports as folder and show every xlsx that doesn't (/V Displays only the non-matching lines) contain "delete" (/I mean insensitive)
In a batch file you can replace /P . by any variable path /P "%~dp0" /P "%CD%" or send as argument /P %1
Also you can do FOR loop to make any command for every match.
In one line to put in console:
FOR /F "usebackq delims=" %A in (`forfiles /p . /s /m *.xlsx /D -365 /C "cmd /c ECHO #path" ^|FINDSTR "\\Exports\\" ^|FINDSTR /I /C:Delete /V`) DO #ECHO FAKE-COMMAND %A
In a batch file:
#ECHO OFF
SETLOCAL ENABLEDELAYEDEXPANSION
FOR /F "usebackq delims=" %%A in (
`forfiles /p . /s /m *.xlsx /D -365 /C "cmd /c ECHO #path" ^|FINDSTR "\\Exports\\" ^|FINDSTR /I /C:Delete /V`
) DO (
SET "myfile=%%~A"
#ECHO FAKE-COMMAND "!myfile!"
)
ENDLOCAL
GOTO :EOF

Find in “xxx” folder today files that containing “yyy” string inside and copy those files to “zzz” folder using batch script

I'm trying to do these:
Search "YYY" string inside 0-day files in "XXX" folder
Copy those files to "ZZZ" existing folder
Rename only those files at the destination folder to "Currency_%date%_#xy.bak"
I guess it can be done with forfiles and findstr commands or through for /f loop.
I tried to start from:
For /F "Tokens=* Delims=" %%I In ('forfiles /M *.bak /S /D 1') Do (Findstr /m "yyy" %%I)
forfiles /D 1 would get files created tomorrow or later.
Use /D 0 (which is "today or later")
Also by default, forfiles give you only the filenames without the path, so findstr can't find them, if they are in subdirectories. To correct this behaviour, use:
for /f "delims=" %%i in ('FORFILES /s /M *.bak /C "cmd /c echo #path"') do ( findstr /m "yyy" %%i && copy "%%i" "zzz\" )
see forfiles /? for more infos.

a batch file to delete a folder which is inside another folder

On windows 7, How can i write a batch file to delete a folder which is inside another folder.
this 'another folder' name varies.
Eg: C:\Users\%USERNAME%\AppData\Local\Mozilla\Firefox\Profiles\xxxxxx\cache2
the 'xxxxxx' might change. Now, i want to delete the 'cache2' folder and all its contents.
i tried this:
:: Batch script to clear browsing history, download history, and empty the cache for Mozila Firefox.
:: Script can be run via GFI MAX RM
#echo off
TASKKILL /T /F /IM Firefox.exe
set DataDir=C:\Users\%USERNAME%\AppData\Local\Mozilla\Firefox\Profiles
del /q /s /f "%DataDir%"
rd /s /q "%DataDir%"
for /d %%x in (C:\Users\%USERNAME%\AppData\Roaming\Mozilla\Firefox\Profiles\*) do del /q /s /f %%x\*sqlite
start "" "C:\Program Files (x86)\Mozilla Firefox\firefox.exe"
cls
IF %ERRORLEVEL%==0 (
#echo "Success Message"
timeout 10
) ELSE (
#echo "Error Message"
timeout 10
exit 1001
)
but this is deleting the entire profiles folder.
can anyone out there please help me out with this.
for /d %%a in (
"C:\Users\%USERNAME%\AppData\Local\Mozilla\Firefox\Profiles\*"
) do if exist "%%~fa\cache2\" echo rmdir /s /q "%%~fa\cache2"
For each folder under the Profiles folder, if it contains a cache2 subfolder, remove it.
rmdir commands are only echoed to console. If the output is correct, remove the echo command
simple:
rmdir /s C:\Users\%USERNAME%\AppData\Local\Mozilla\Firefox\Profiles\xxxxxx\cache2
If you know that your cache2 folder is a direct child of xxxxxx, then MC ND has a good answer. But if cache2 can appear at any level, then the following works, providing that cache2 is not a direct decendent of "...\Profiles\".
#echo off
for /f "delims=" %%F in ('dir /b /ad /s "C:\Users\%USERNAME%\AppData\Local\Mozilla\Firefox\Profiles\cache2"') do echo rd /s /q "%%F"
If cache2 can be a direct child of "...\Profiles", then the following should work as long as there are no folders with a name like "cache2.x".
#echo off
for /f "delims=" %%F in ('dir /b /ad /s "C:\Users\%USERNAME%\AppData\Local\Mozilla\Firefox\Profiles\cache2.?"') do echo rd /s /q "%%F"
Both commands above simply ECHO the RD statements. Simply remove ECHO when all looks correct.

Resources