Improve company productivity with a Business Account.Sign Up

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 3710
  • Last Modified:

Batch script to delete empty folders?

Hi all,

Following on from some excellent help from knightEknight on this script:
http://www.experts-exchange.com/Programming/Languages/Scripting/Shell/Batch/Q_28273418.html


I'm now in need of a script to recursively search for and delete empty folders.

so i have a root folders called:

+Media

This has say 3 folders, with one of the folders having a subfolder:

+Folder1
+Folder2
+Folder3
....+Folder3a

Only Folder2 has files in it, all of the others need to be deleted.


Any idea how to write a batch file to achieve this?

Thanks,
0
TheDadCoder
Asked:
TheDadCoder
  • 11
  • 8
  • 6
1 Solution
 
Bill PrewCommented:
Here's a simple VBS script that can be used to do what you described, save as a VBS and update the base dir path at the top.

It currently prints the folders it removes, but if you want it to run silently just remove the Wscript.Echo line.

Const strBaseDir = "C:\EE\EE28281260\Files"

set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

RemoveFolder objFSO.GetFolder(strBaseDir)

Sub RemoveFolder(objFolder)
    For Each objSubFolder In objFolder.Subfolders
        RemoveFolder objSubFolder
    Next
    If objFolder.Files.Count = 0 And objFolder.Subfolders.Count = 0 Then
        Wscript.Echo objFolder.Path
        objFolder.Delete
    End If
End Sub

Open in new window

~bp
0
 
wilcoxonCommented:
If you have cygwin or other Unix environment installed on your Windows then you can do it with a very simple shell command.
find . -depth -type d -empty -exec rmdir {} \;

Open in new window


I was going to use find2perl to generate a perl script to do it but apparently find2perl doesn't support -empty so it becomes more difficult...
0
 
TheDadCoderAuthor Commented:
Hi billprew - thanks I'll try that script.

Hi wilcoxon, I'm not using cygwin or any unix system here, thanks anyway.
0
Get expert help—faster!

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

 
TheDadCoderAuthor Commented:
Hi billprew, I've tested your vbs script and for normal files it works, of course.

However, I've noticed that some folders that appeared empty it failed to delete them.  upon inspection this was due to hidden files, such as thumbs.db.

Any ideas how it can still delete if it finds a file that's to delete?

or is it just easier to do a windows find and delete first?
0
 
wilcoxonCommented:
It depends.  Are all the files in the "empty" directories 0-size files so should be removed by the script?  If so, you need to do a depth-first traversal so it will see the 0-size files before it checks if the directory is empty.
0
 
TheDadCoderAuthor Commented:
Hi - no these are system files that store icon pos values, and other stuff, which in this situation are not needed.

I'm thinking a list of files to always delete... but it might just be easier to delete these via windows search first.
0
 
wilcoxonCommented:
A list of filenames to always delete or to delete only if they are the only files in a folder (eg leave alone if the folder is not otherwise empty) should work fine.  I should have time tomorrow sometime to work up a perl solution...
0
 
Bill PrewCommented:
Sounds like it might be easiest, and safest, to just delete the desired files, and then run the script to remove the empty folders.

~bp
0
 
wilcoxonCommented:
Here's a perl solution...
use strict;
use warnings;
use File::Find ();

# for the convenience of &wanted calls, including -eval statements:
use vars qw/*name *dir *prune/;
*name   = *File::Find::name;
*dir    = *File::Find::dir;
*prune  = *File::Find::prune;

use Cwd ();
my $cwd = Cwd::cwd();

my $base = shift || 'C:/EE/EE282281260/Files'; # pass in or default

# change this to include the files you want to remove if they are the
# only ones in the directory
my @files_to_rm = (qw(thumbs.db anotherfile and_another));
my %files_to_rm = map { $_ => 1 } @files_to_rm;

# Traverse desired filesystems
File::Find::finddepth({wanted => \&wanted}, $base);
exit;

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid) = lstat($_);
    if (-f _ and int(((-s _) + 511) / 512) == 0) {
        unlink $name or die "could not rm $name: $!";
    } elsif (-d _) {
        opendir DIR, $name or die "could not open dir $name: $!";
        my @files = grep !m{^\.+$}, readdir DIR;
        closedir DIR;
        my @del = grep { exists $files_to_rm{$_} } @files;
        # there are no files or all files are ones to remove
        if (@files == @del or @files == 0) {
            foreach my $fil (@files) {
                unlink "$name/$fil" or die "could not rm $name/$fil: $!";
            }
            system('rmdir', $name) == 0 or die "rmdir failed: $?";
        }
    }
}

Open in new window

0
 
Bill PrewCommented:
Give this a try:

Const strBaseDir = "C:\EE\EE28281260\Files"

arrFilesToDelete = Array("thumbs.db", "desktop.ini")

set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

RemoveFolder objFSO.GetFolder(strBaseDir)

Sub RemoveFolder(objFolder)
    For Each objSubFolder In objFolder.Subfolders
        RemoveFolder objSubFolder
    Next
    For Each objFile in objFolder.Files
        For Each strFileToDelete in arrFilesToDelete
            If LCase(strFileToDelete) = LCase(objFile.Name) Then
                objFile.Delete(True)
            End If
        Next
    Next
    If objFolder.Files.Count = 0 And objFolder.Subfolders.Count = 0 Then
        Wscript.Echo objFolder.Path
        objFolder.Delete
    End If
End Sub

Open in new window

~bp
0
 
TheDadCoderAuthor Commented:
Another script to test :)
0
 
wilcoxonCommented:
Just wondering if you've had time to test the perl script I submitted?  If so, any issues with how it worked?
0
 
TheDadCoderAuthor Commented:
Hi wilcoxon - how do you run the perl script?

billprew - yours works as needed thanks.
0
 
TheDadCoderAuthor Commented:
Hi billprew,

I added an additional filename to the script as below but I get an error now.   I guess it doesn't like the mac os filename '.DS_Store'?


Any ideas?

invalid procedure call or arguement
code: 800A0005
Line: 21:
char: 8


Const strBaseDir = "v:\"

arrFilesToDelete = Array("thumbs.db", "desktop.ini", ".DS_Store")

set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

RemoveFolder objFSO.GetFolder(strBaseDir)

Sub RemoveFolder(objFolder)
    For Each objSubFolder In objFolder.Subfolders
        RemoveFolder objSubFolder
    Next
    For Each objFile in objFolder.Files
        For Each strFileToDelete in arrFilesToDelete
            If LCase(strFileToDelete) = LCase(objFile.Name) Then
                objFile.Delete(True)
            End If
        Next
    Next
    If objFolder.Files.Count = 0 And objFolder.Subfolders.Count = 0 Then
       objFolder.Delete
    End If
End Sub

Open in new window

0
 
TheDadCoderAuthor Commented:
Hi billprew - ignore my last comment.  It deletes the files with the new filename fine, however the error seems to come from the delete command when the basedir is empty, i.e. nothing to delete, but it tries to delete anyway, but since there's nothing to delete it fails.

Not a major issue, but it'd be nice to return an message saying "Nothing to delete!", or something.

Is this possible?
0
 
Bill PrewCommented:
So are you saying there are no files or folders under v:\, but it is trying to delete v:\? Naturally deleting a root folder of a drive will fail, that's not allowed, but I'm surprised you are actually empty on v:\?

We would actually want to check the folder name I suspect, and handle this special case, the root folder, if that's what you are seeing.

~bp
0
 
wilcoxonCommented:
Sorry.  You had posted in the Perl topic so I assumed you knew how to run Perl...

In order to run a perl script, you need to have perl installed.  If you are on Mac, I'm pretty sure it is standard.  If you are on Windows then you probably need to install one - I'd suggest Strawberry Perl.

Once it is installed, you should be able to type "perl <script name> <script arguments>" (replacing the items in <> with the actual names/values).  If you are on Windows, you'll likely need to open "Perl (command line)" (or something similar) rather than the normal command prompt to run it (I'm not sure why it gets installed that way as I believe the only difference is some environment variables).
0
 
TheDadCoderAuthor Commented:
Hi billprew,  v: drive is just a mapped drive to my polling folder, nothing special.  The end result would be that folder, that v drive points to, is empty.  or not empty and i know i have files i need to clear out manually.

I don't know if it's trying to delete v drive, but the code looks like it's running the delete command but i suspect there's nothing to delete.

This is confusing because your last section eval's if files and folder count =0.
0
 
Bill PrewCommented:
Thy this small workaround.

Const strBaseDir = "v:\"

arrFilesToDelete = Array("thumbs.db", "desktop.ini", ".DS_Store")

set objFSO = WScript.CreateObject("Scripting.FileSystemObject")

RemoveFolder objFSO.GetFolder(strBaseDir)

Sub RemoveFolder(objFolder)
    For Each objSubFolder In objFolder.Subfolders
        RemoveFolder objSubFolder
    Next
    For Each objFile in objFolder.Files
        For Each strFileToDelete in arrFilesToDelete
            If LCase(strFileToDelete) = LCase(objFile.Name) Then
                objFile.Delete(True)
            End If
        Next
    Next
    If objFolder.Files.Count = 0 And objFolder.Subfolders.Count = 0 Then
       If Len(objFolder.Path) > 3 Then
           objFolder.Delete
       End If
    End If
End Sub

Open in new window

~bp
0
 
TheDadCoderAuthor Commented:
Just perfect, thank you.
0
 
wilcoxonCommented:
Why no recent comments about my script and no splitting of the points?  The perl script I submitted did exactly what you requested.
0
 
TheDadCoderAuthor Commented:
Hi  wilcoxon,

I thank you for assistance, however I voted to use the alt script as it was quicker to just use, rather than install perl.

Thanks anyway.
0
 
wilcoxonCommented:
May I suggest, in future, not including the "Perl Programming Language" topic if you don't want to install Perl?
0
 
TheDadCoderAuthor Commented:
you may.
0
 
Bill PrewCommented:
Welcome.

~bp
0
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.

Join & Write a Comment

Featured Post

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

  • 11
  • 8
  • 6
Tackle projects and never again get stuck behind a technical roadblock.
Join Now