TheDadCoder
asked on
Batch script to delete empty folders?
Hi all,
Following on from some excellent help from knightEknight on this script:
https://www.experts-exchange.com/questions/28273418/Script-to-find-duplicate-files-but-not-using-filename-filesize.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,
Following on from some excellent help from knightEknight on this script:
https://www.experts-exchange.com/questions/28273418/Script-to-find-duplicate-files-but-not-using-filename-filesize.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,
If you have cygwin or other Unix environment installed on your Windows then you can do it with a very simple shell command.
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...
find . -depth -type d -empty -exec rmdir {} \;
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...
ASKER
Hi billprew - thanks I'll try that script.
Hi wilcoxon, I'm not using cygwin or any unix system here, thanks anyway.
Hi wilcoxon, I'm not using cygwin or any unix system here, thanks anyway.
ASKER
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?
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?
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.
ASKER
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.
I'm thinking a list of files to always delete... but it might just be easier to delete these via windows search first.
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...
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
~bp
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: $?";
}
}
}
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
~bp
ASKER
Another script to test :)
Just wondering if you've had time to test the perl script I submitted? If so, any issues with how it worked?
ASKER
Hi wilcoxon - how do you run the perl script?
billprew - yours works as needed thanks.
billprew - yours works as needed thanks.
ASKER
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?
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
ASKER
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?
Not a major issue, but it'd be nice to return an message saying "Nothing to delete!", or something.
Is this possible?
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
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
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).
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).
ASKER
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.
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.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Just perfect, thank you.
Why no recent comments about my script and no splitting of the points? The perl script I submitted did exactly what you requested.
ASKER
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.
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.
May I suggest, in future, not including the "Perl Programming Language" topic if you don't want to install Perl?
ASKER
you may.
Welcome.
~bp
~bp
It currently prints the folders it removes, but if you want it to run silently just remove the Wscript.Echo line.
Open in new window
~bp