Link to home
Start Free TrialLog in
Avatar of tech-
tech-

asked on

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!
Avatar of ReneGe
ReneGe
Flag of Canada image

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

@echo off
for /f "tokens=*" %%a in ('dir /ad /b /s d:\data\work\file') do del /f /s /q "%%a"
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

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!!
Avatar of Steve Knight
hmm , too late as usual.... Was going to do rd /s/q after for /d/r or dir as you did.

Steve
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?
ASKER CERTIFIED SOLUTION
Avatar of Paul Tomasi
Paul Tomasi
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
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?
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

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
Feels like we'r all hungry for people asking questions ;-)
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
@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
Avatar of tech-
tech-

ASKER

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!!!
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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!
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
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

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
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?
@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
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

@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

@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

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....
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
Sorry guys...
Just making my point, with comparing FOR /R and /F speed of execution, found in some proposed solution.
for /r/d works on dirs so doubt you have any .txt dirs?
Oups! You'r right!
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

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
Must have been BillDL cause I did'nt know about it as well.
This was the first place I noticed it I think, props to knightEknight for me.

https://www.experts-exchange.com/questions/27316011/rename-multiple-files-in-multiple-folder.html

~bp
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@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
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

Or frankly: http:#36903830 or http:#36903625 before that etc....
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

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
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.
Avatar of tech-

ASKER

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!!!