Batch Script to Parse Folders within Subfolders to delete specific Folders and Files within

I need a batch script to parse folders and subfolders to delete a folder called "junk" and the contents within those folders.

D:\DATA\WORK\*.* contains folders and within those folders is folders called "junk" that need to be deleted.

Hopefully this is clear, let me know.

Thanks EE Team!
tech-Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ReneGeCommented:
Here you go
@ECHO OFF

FOR /F "delims=" %%A IN ('DIR /AD /B /S "D:\DATA\WORK\*.*"') DO (
	IF /i "%%~nA" EQU "JUNK" (
		ECHO DELETING "%%~fA"
		RD /S /Q "%%~fA"
	)
)

PAUSE
EXIT

Open in new window

0
Paul TomasiCommented:
@echo off
for /f "tokens=*" %%a in ('dir /ad /b /s d:\data\work\file') do del /f /s /q "%%a"
0
Paul TomasiCommented:
If you want a REALLY fast solution, run this:


@echo off

for /r d:\data\work\ %%a in (junk) do (
   Del /f /s /q "%%~dpna"
)

Open in new window

0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

Paul TomasiCommented:
Oops! Just noticed in my first comment (36903169) I left the foldername 'file' instead of 'junk' in there. It should have been:

   @echo off
   for /f "tokens=*" %%a in ('dir /ad /b /s d:\data\work\junk') do del /f /s /q "%%a"

However, please see my most previous comment above. It's fast - lightning fast!!
0
Steve KnightIT ConsultancyCommented:
hmm , too late as usual.... Was going to do rd /s/q after for /d/r or dir as you did.

Steve
0
Steve KnightIT ConsultancyCommented:
oh what the hell... Might aswell add this one in:

@echo off
for /r/d %%a in ("junk") do rd /q/s "%%~a"

not tested but think that should do it?
0
Paul TomasiCommented:
If you want to add a visual indication of progress then you could add the following line:

   title %%~dpna

as in the following example:


@echo off

for /r d:\data\work\ %%a in (junk) do (
   title %%~dpna
   del /f /s /q "%%~dpna"
)

Open in new window


This displays the folder string in titlebar of the DOS window. If you run DOS in full-screen mode then it will have no effect in which case include this line instead:

   echo Deleting  %%~dpna

as in the following:

@echo off

for /r d:\data\work\ %%a in (junk) do (
   echo Deleting %%~dpna
   del /f /s /q "%%~dpna"
)

Open in new window


Finally, if you want a log file of all the directories deleted then you need to redirect output to a file like this:

@echo off

(for /r d:\data\work\ %%a in (junk) do (
   echo Deleting %%~dpna
   del /f /s /q "%%~dpna"
))>file.log

Open in new window


This will create a file FILE.LOG (but you might want to use a name of your own choosing). Open this file using Notepad in DOS.

   Notepad file.log

And that's all there is to it.

Oh, one final point, if you want to APPEND output to an existing log file then use this instead (admitedly it's a bit slower than the one above however, it's probably the most conventional way of doing it):


@echo off

for /r d:\data\work\ %%a in (junk) do (
   echo Deleting %%~dpna >>file.log
   del /f /s /q "%%~dpna"
)

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Paul TomasiCommented:
Hey Steve (dragon-it)...

Just noticed you posted:

   for /r/d %%a....

I've never seen this before. I also notice you're using FOR /R but in the absence of including a directoryname as opposed to the following:

   for /r c:\folder %%a....

I see you've included junk (obviously this had to appear somewhere) and I notice you've enclosed it in double-quotes.... Was this deliberate or just habit?

The /r/d is new to me. Does it actually work?
0
Paul TomasiCommented:
tech-

If for some reason my batch files above do not work as expected then please try this (it's fast - extremely fast!!):


@echo off
for /r d:\data\work\ %%a in (junk) do rd /s /q "%%~dpna"

Open in new window


If you want a visual the try this:

@echo off
for /r d:\data\work\ %%a in (junk) do (
   echo Deleting %%~dpna
   rd /s /q "%%~dpna"
)

Open in new window

0
Steve KnightIT ConsultancyCommented:
Er yes... was trying to post it as an alternative while walking for bus, BT Total **** business broadband had helpfully killed office broadband on and off for several hours so had given up and gone home.  Amusingly, once I'd got through to someone it was apparently down to a power failure at "their authentication server".... dread to think why it isn't clustered across multiple sites "in the cloud"!!

Anyway I digress.  I think ReneGe is where I first saw this for /r /d and what I should have out was:

for /d /r %a in (junk.*) do @rd /s /q "%~a"

Or from batch file use %%a instead of %a of course.

Steve
0
ReneGeCommented:
Feels like we'r all hungry for people asking questions ;-)
0
Steve KnightIT ConsultancyCommented:
Main advantage over for /d /r over for /f and ('dir....') is that the dir runs first and for /r runs as it goes along.

Advantage over just for /r is it doesn't have to process all the files in those dirst looking for matches, just the dir names.

I haven't got hundred or thousands of dirs setup to test against but the one liner above is instant on couple of dozen test dirs.

Steve
0
ReneGeCommented:
@dragon-it:

I have a folder containing arroung a million files. The batch file I use to process these uses FOR /F ('DIR...') not /R because like you say, it starts quicker than /F but more it goes, more it slows down and finally, taks a lot more time than /F.

Cheers
0
tech-Author Commented:
Thanks to all!  I like the fact that everything is logged... (paultomasi)

@echo off

for /r d:\data\work\ %%a in (junk) do (
   echo Deleting %%~dpna >>file.log
   del /f /s /q "%%~dpna"
)

I am in a production environment and checking with the software provider to verify this process won't damage anything.   Obviously I need to get a good backup prior to executing, so it may be later tonight when I close this solution...

Thanks again!!!
0
Steve KnightIT ConsultancyCommented:
Hmm, I wonder at what point it becomes slower then?

@echo off
echo %time% for /f start
(for /f "tokens=*" %%a in ('dir /b /s /ad') do echo %%a)> NUL
echo %time% for /f stop
echo %time% for /r start
(for /r /d %%a in (*.*) do echo %%a) >NUL
echo %time% for /r stop

C:\>"1. DATA"\1.cmd
15:44:16.05 for /f start
15:44:28.47 for /f stop
15:44:28.47 for /r start
15:44:32.25 for /r stop

and in the other order:

C:\>"1. DATA"\1.cmd
15:46:05.18 for /r start
15:46:08.91 for /r stop
15:46:08.91 for /f start
15:46:21.28 for /f stop

This is based on drive with:
         136572 File(s) 350,901,906,993 bytes
           58205 Dir(s)  579,228,450,816 bytes free
0
ReneGeCommented:
@tech-:
Why don't you move the folders instead of deleting them?

@dragon-it:
Me and BillPrew did a big tread testing both and we both came to the same conclusion. I'll try to find it!
0
Steve KnightIT ConsultancyCommented:
I'd do this then I guess... whcih pretty well is ReneGe's first post but using for /r instead, and logged ... Paul's option deletes the files but not the dirs unless I am missing something.  If you want the files logged too then try #2 below.

@echo off
cd /d D:\data\work
(for /d /r %%a in (junk.*) do @rd /s /q "%%~a") > log.txt
start notepad log.txt

#2 ... delete files first, then directories in order to log them

@echo off
cd /d D:\data\work
(for /d /r %%a in (junk.*) do
  del /s /q /f "%%~a\*.*"
  rd /s /q "%%~a"
) > log.txt
start notepad log.txt
0
ReneGeCommented:
FOR /F vs /R

11:45:35.45 F START
11:47:22.18 F END
11:47:22.18 R START
11:50:18.01 R END
@echo off
SETLOCAL enabledelayedexpansion
SET LogFile=%~n0.log

ECHO CREATING TEST FILES

for /l %%a in (1,1,50) do for /l %%b in (0,1,9) do for /l %%c in (0,1,9) do for /l %%d in (0,1,9) do (
	SET Folder=.\Test\%%a\%%b\%%c
	IF NOT EXIST "!Folder!" MD "!Folder!"
		ECHO %%a%%b%%c%%d
		ECHO %%a%%b%%c%%d>"!Folder!\%%a%%b%%c%%d.TXT"
)

:jump

IF EXIST "%LogFile%" DEL "%LogFile%"

echo %time% TEST FOR F
echo %time% F START>>"%LogFile%"
for /f %%A in ('DIR /S /B /A-D *.txt') DO IF /i %%~nxA EQU 50999.txt ECHO %%~nxA
echo %time% F END>>"%LogFile%"

echo %time% TEST FOR R
echo %time% R START>>"%LogFile%"
for /R "%~dp0" %%A in (*.txt) DO IF /i %%~nxA EQU 50999.txt ECHO %%~nxA
echo %time% R END>>"%LogFile%"

PAUSE

Open in new window

0
Steve KnightIT ConsultancyCommented:
OK 2:56 against 1:47 then :-)

Do you want to try that with for /r /d as matter of interest... on way out at moment but will try myself too later,

Steve
0
ReneGeCommented:
Yes but before, a good while ago, while testing things with BillP, he intruduced to me, an app that was calculating the time ellaps between executions from within a batch file. Have any ideas?
0
Bill PrewCommented:
@ReneGe

I use TIMER.EXE from the link below.  Fairly basic but gets the job done for this type of stuff.

http://www.gammadyne.com/cmdline.htm

~bp
0
ReneGeCommented:
Thanks bp for the reminder

12:29:52.39 F START
99.5 seconds
12:31:31.90 F END
12:31:31.90 D R START

12:32:23.75 F START
1 minute, 41 seconds
12:34:05.09 F END
12:34:05.09 D R START
0
ReneGeCommented:

@echo off
SETLOCAL enabledelayedexpansion
SET LogFile=%~n0.log

REM GOTO JUMP

ECHO CREATING TEST FILES

for /l %%a in (1,1,50) do for /l %%b in (0,1,9) do for /l %%c in (0,1,9) do for /l %%d in (0,1,9) do (
	SET Folder=.\Test\%%a\%%b\%%c
	IF NOT EXIST "!Folder!" MD "!Folder!"
		ECHO %%a%%b%%c%%d
		ECHO %%a%%b%%c%%d>"!Folder!\%%a%%b%%c%%d.TXT"
)

:jump

ECHO.>>"%LogFile%"
echo %time% TEST FOR F
echo %time% F START>>"%LogFile%"
timer.exe /nologo /q
for /f %%A in ('DIR /S /B *.txt') DO IF /i %%~nxA EQU 50999.txt ECHO %%~nxA
timer.exe /nologo /s>>"%LogFile%"
echo %time% F END>>"%LogFile%"

echo %time% TEST FOR D R
echo %time% D R START>>"%LogFile%"
timer.exe /nologo /q
for /r /d %%a in %%A in (*.txt) DO IF /i %%~nxA EQU 50999.txt ECHO %%~nxA
timer.exe /nologo /s>>"%LogFile%"
echo %time% R END>>"%LogFile%"


echo %time% TEST FOR R
echo %time% R START>>"%LogFile%"
timer.exe /nologo /q
for /R "%~dp0" %%A in (*.txt) DO IF /i %%~nxA EQU 50999.txt ECHO %%~nxA
timer.exe /nologo /s>>"%LogFile%"
echo %time% R END>>"%LogFile%"

PAUSE

Open in new window

0
ReneGeCommented:
@Steve
Can't seem to make "for /d /r" working, cause there is no output

Here are the recent results:
TEST FOR /D /R
4.6 seconds

TEST FOR /F
2 minutes, 3 seconds

TEST FOR /R
FOUND [50999.TXT]50999.TXT
4 minutes, 40 seconds


@echo off
SETLOCAL enabledelayedexpansion
SET LogFile=%~n0.log

GOTO JUMP

ECHO CREATING TEST FILES

for /l %%a in (1,1,50) do for /l %%b in (0,1,9) do for /l %%c in (0,1,9) do for /l %%d in (0,1,9) do (
	SET Folder=.\Test\%%a\%%b\%%c
	IF NOT EXIST "!Folder!" MD "!Folder!"
		ECHO %%a%%b%%c%%d
		ECHO %%a%%b%%c%%d>"!Folder!\%%a%%b%%c%%d.TXT"
)

:jump

ECHO TEST FOR ^/D ^/R
ECHO TEST FOR ^/D ^/R>>"%LogFile%"
timer.exe /nologo /q
for /d /r %%A in (*.txt) DO (
	ECHO %%A
	IF /i %%~nxA EQU 50999.txt ECHO FOUND [%%~nxA]>>"%LogFile%"
)
timer.exe /nologo /s>>"%LogFile%"
ECHO.>>"%LogFile%"

ECHO TEST FOR ^/F
ECHO TEST FOR ^/F>>"%LogFile%"
timer.exe /nologo /q
for /f %%A in ('DIR /S /B *.txt') DO IF /i %%~nxA EQU 50999.txt ECHO FOUND [%%~nxA]%%~nxA>>"%LogFile%"
timer.exe /nologo /s>>"%LogFile%"
ECHO.>>"%LogFile%"

ECHO TEST FOR ^/R
ECHO TEST FOR ^/R>>"%LogFile%"
timer.exe /nologo /q
for /R "%~dp0" %%A in (*.txt) DO IF /i %%~nxA EQU 50999.txt ECHO FOUND [%%~nxA]%%~nxA>>"%LogFile%"
timer.exe /nologo /s>>"%LogFile%"

PAUSE

Open in new window

0
Paul TomasiCommented:
Blimey! I go out for a few hours and all hell breaks loose!

Going to take quite a while to read through all this lot....
0
Bill PrewCommented:
I hear you paul!  I decided to sit this one out since a couple of viable solutions were presented early, and since there are only so many ways to approach this.  It certainly has taken on a life of it's own now though...

~bp
0
ReneGeCommented:
Sorry guys...
Just making my point, with comparing FOR /R and /F speed of execution, found in some proposed solution.
0
Steve KnightIT ConsultancyCommented:
for /r/d works on dirs so doubt you have any .txt dirs?
0
ReneGeCommented:
Oups! You'r right!
0
ReneGeCommented:
And the final winner is... Steve!!!

TEST FOR /R /D
45.7 seconds

TEST FOR /F
3 minutes, 7 seconds

@echo off
SETLOCAL enabledelayedexpansion
SET LogFile=%~n0.log

rem GOTO JUMP

ECHO CREATING TEST FILES

for /l %%a in (1,1,50) do for /l %%b in (0,1,9) do for /l %%c in (0,1,9) do (
	echo %%a%%b%%c
	for /l %%d in (0,1,9) do MD .\Test\%%a\%%b\%%c\%%d
)

:jump
ECHO ------------------------>>"%LogFile%"

ECHO TEST FOR ^/R ^/D
ECHO TEST FOR ^/R ^/D>>"%LogFile%"
timer.exe /nologo /q
for /r /d %%A in (*.*) DO ECHO.>NUL
timer.exe /nologo /s>>"%LogFile%"
ECHO.>>"%LogFile%"

ECHO TEST FOR ^/F
ECHO TEST FOR ^/F>>"%LogFile%"
timer.exe /nologo /q
for /f "delims=" %%A in ('DIR /S /B /AD') DO ECHO.>NUL
timer.exe /nologo /s>>"%LogFile%"
ECHO.>>"%LogFile%"

PAUSE

Open in new window

0
Steve KnightIT ConsultancyCommented:
And frankly none of us really knew that option existed until recently?  Well I didn't anyway until I saw you use it I think Rene, or maybe it was BillDL?

I suppose it is logical.... ish.  And I see you did the /F second so if anything that should have been cached more.

Your test batch Rene, 10.6 secs for /R/D and 29.2 for /F on mine... somewhat faster?!

Steve
0
ReneGeCommented:
Must have been BillDL cause I did'nt know about it as well.
0
Bill PrewCommented:
This was the first place I noticed it I think, props to knightEknight for me.

http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Windows/XP/Q_27316011.html

~bp
0
ReneGeCommented:
0
ReneGeCommented:
@tech-

In conclusion, and based on your 36903702 comment, the following seems to be the fastest and most complete working solution:

 
@ECHO OFF
SET LogFile=LogFile.log
FOR /R /D %%A IN (junk.*) DO (
	ECHO "%%~fA"
	ECHO "%%~fA">>"%LogFile%"
	RD /S /Q "%%~fA"
)
PAUSE
EXIT

Open in new window


Feel free to split points, as we all somehow contributed!

Cheers,
Rene
0
Paul TomasiCommented:
I noticed errors in my previous programs so I'm re-submitting here.

The best solution I can find at the moment is loosely based on ReneGe's solution directly above:

@echo off

for /d /r d:\data\work %%a in (junk.*) do (
   echo %%a
   echo %%a>>logfile.txt
   rd /q /s "%%a"
)

Open in new window

0
Steve KnightIT ConsultancyCommented:
Or frankly: http:#36903830 or http:#36903625 before that etc....
0
Paul TomasiCommented:
Okay, when I said loosely based on  ReneGe's solution, I meant VERY loosely...

In fact the more I look at it the less it looks like any of yours' solutions!

The '/D/R' pair is really great. This has opended up a new area to explore.

Specifying 'junk.*' does away with those silly appendices in FOR /R.

An added feature I discovered is the inclusion of a base directory - extremely handy (and neat)!

In my code, there is no need to CD into the base directory (unlike other examples).

It has to be bourne in mind that none of the methods reliant solely on /D/R are reliable and would require additional filtering.

Here are some questions:

What happens if:

   1) A folder named 'JUNK.DIR' is encountered?

   2) A file named 'JUNK' is encountered?

   3) A file named 'JUNK.FILE' is encountered?

Maybe a better approach is something along these lines:

@echo off

for /d /r d:\data\work %%a in (*) do (
   if /i "%%~nxa"=="junk" (
      echo %%a
      echo %%a>>logfile.txt
      rd /q /s "%%a"
   )
)

Open in new window

0
Steve KnightIT ConsultancyCommented:
but Paul that brings you back to processing every folder and parsing it for junk rather than just looking for junk.

Still maintain its just a rejigged version before of what was always there, i.e. For /r/d and rd /s/q with junk. As filter?!

i'm not sure what happens then too since you are pulling the rug out from under for /r that is wanting to go into the next subdir of that junk folder etc?

steve
0
Paul TomasiCommented:
Steve (dragon-it)

   for /d /r d:\data\work %%a in (*) do (

will:

   excludes all filenames
   includes ALL foldernames


   if /i "%%~nxa"=="junk" (

will:

   includes ONLY folders named 'junk' (excludes all folders with extensionnames)


>> "...that brings you back to processing every folder..."

Of course it does because for /d /r d:\data\work %%a in (*) do ( returns ALL folders rooted at d:\data\work\.

>> "...rather than just looking for junk."

Yes, because for /d /r d:\data\work %%a in (junk.*) do ( ('junk.*' or just 'junk*') will return ANY folder beginning with the letters 'JUNK' including: JUNK.EXT, JUNK001 and JUNK001.EXT.
0
tech-Author Commented:
I used this solution:

@echo off

for /r d:\data\work\ %%a in (junk) do (
   echo Deleting %%~dpna >>file.log
   del /f /s /q "%%~dpna"
)

It kept the folder named junk but removed the files. (Which I am actually happy with because now I know if there was a junk folder or not, I can go back to my backup before this purge and retrieve files if needed)

It took 36 hours to process 450GB of data, 2.3 Million files in 500,000 folders!  It deleted about 500,000 files and reduced the size by 100GB.   Mission accomplished!

Thanks for all who participated!  I wish I could give you each 1000 points!!!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft DOS

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.