?
Solved

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

Posted on 2011-10-03
41
Medium Priority
?
416 Views
Last Modified: 2012-05-12
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!
0
Comment
Question by:tech-
  • 15
  • 11
  • 10
  • +2
41 Comments
 
LVL 10

Expert Comment

by:ReneGe
ID: 36903144
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
 
LVL 11

Expert Comment

by:paultomasi
ID: 36903169
@echo off
for /f "tokens=*" %%a in ('dir /ad /b /s d:\data\work\file') do del /f /s /q "%%a"
0
 
LVL 11

Expert Comment

by:paultomasi
ID: 36903230
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 11

Expert Comment

by:paultomasi
ID: 36903240
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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36903261
hmm , too late as usual.... Was going to do rd /s/q after for /d/r or dir as you did.

Steve
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36903305
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
 
LVL 11

Accepted Solution

by:
paultomasi earned 668 total points
ID: 36903321
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
 
LVL 11

Expert Comment

by:paultomasi
ID: 36903354
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
 
LVL 11

Expert Comment

by:paultomasi
ID: 36903388
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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36903625
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36903633
Feels like we'r all hungry for people asking questions ;-)
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36903646
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36903667
@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
 

Author Comment

by:tech-
ID: 36903702
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
 
LVL 43

Assisted Solution

by:Steve Knight
Steve Knight earned 668 total points
ID: 36903748
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36903792
@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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36903830
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36904177
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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36904203
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36904262
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
 
LVL 59

Expert Comment

by:Bill Prew
ID: 36904310
@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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36904703
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36904710

@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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36904996
@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
 
LVL 11

Expert Comment

by:paultomasi
ID: 36905071
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
 
LVL 59

Expert Comment

by:Bill Prew
ID: 36905102
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36905128
Sorry guys...
Just making my point, with comparing FOR /R and /F speed of execution, found in some proposed solution.
0
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36905432
for /r/d works on dirs so doubt you have any .txt dirs?
0
 
LVL 10

Expert Comment

by:ReneGe
ID: 36905704
Oups! You'r right!
0
 
LVL 10

Expert Comment

by:ReneGe
ID: 36905858
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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36906819
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
 
LVL 10

Expert Comment

by:ReneGe
ID: 36906874
Must have been BillDL cause I did'nt know about it as well.
0
 
LVL 59

Expert Comment

by:Bill Prew
ID: 36907047
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
 
LVL 10

Assisted Solution

by:ReneGe
ReneGe earned 664 total points
ID: 36907329
0
 
LVL 10

Expert Comment

by:ReneGe
ID: 36907730
@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
 
LVL 11

Expert Comment

by:paultomasi
ID: 36909910
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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36910016
Or frankly: http:#36903830 or http:#36903625 before that etc....
0
 
LVL 11

Expert Comment

by:paultomasi
ID: 36915029
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
 
LVL 43

Expert Comment

by:Steve Knight
ID: 36915128
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
 
LVL 11

Expert Comment

by:paultomasi
ID: 36915944
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
 

Author Comment

by:tech-
ID: 36943098
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

Featured Post

Important Lessons on Recovering from Petya

In their most recent webinar, Skyport Systems explores ways to isolate and protect critical databases to keep the core of your company safe from harm.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This script will sweep a range of IP addresses (class c only, 255.255.255.0) and report to a log the version of office installed. What it does: 1.)      Creates log file in the directory the script is run from (if it doesn't already exist) 2.)      Sweep…
Recently, an awarded photographer, Selina De Maeyer (http://www.selinademaeyer.com/), completed a photo shoot of a beautiful event (http://www.sintjacobantwerpen.be/verslag-en-fotoreportage-van-de-sacramentsprocessie-door-antwerpen#thumbnails) in An…
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Suggested Courses
Course of the Month15 days, 12 hours left to enroll

850 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question