compare two folders and all nested subfolders, kill all empty folders

Hi all,

I have a music library with lots of sub folders and files inside.
I have just reinstalled a new library with just the default folders sub folders and files in it.
I would like to eliminate all files contained in the new library from the old one in 1 go.
Can anybody modify this so that all nested subfolders are checked and if there are files there already in the new library they get deleted. Also if a folder gets emptied it is deleted.

Thanks for your help.

This is what I came up with so far:


– choose oldLibrary folder
set oldLibrary to (choose folder with prompt “Choose folder containing items to delete:”)
– choose newLibrary folder
set newLibrary to (choose folder with prompt “Choose folder containing items to keep:”) as string
tell application “Finder”
repeat with thisItem in (get items of oldLibrary)
if newLibrary & name of thisItem exists then
if kind of thisItem is not “Folder” then
– if kind of i is “File” then
move thisItem to trash
else
set oldLibrary2 to (oldLibrary & name of thisItem) as text as alias
set newLibrary2 to (newLibrary & name of thisItem) as text as alias
repeat with thatItem in (get items of oldLibrary2)
– return thatItem as text
if (newLibrary2 & name of thatItem) as text as alias exists then
– return (thatItem as text) & " exists"
if kind of thatItem is not “Folder” then
– if kind of i is “File” then
move thatItem to trash
end if
end if
end repeat
if (count items) of thisItem = 0 then move thisItem to trash
– end if
end if
end if
end repeat
if (count items) of (get items of oldLibrary) = 0 then move oldLibrary to trash
end tell

Hi. The direction you want to move in is to remove items from the old folder that are name-matched to items found in the new, correct? This is pretty similar to code I’ve written previously. I didn’t spend much time checking this particular variation, but the logic should be sound. You might want to try first running it on a dummy set of files.


set oldLibrary to (choose folder with prompt "Choose a folder containing items to delete:")
set newLibrary to (choose folder with prompt "Choose a folder containing items to keep:")

tell application "Finder"
	delete (oldLibrary's entire contents's files whose name is in (get newLibrary's entire contents's files's name))
	tell folder oldLibrary's entire contents's folders to delete (it whose name is not in (get files's container's name))
end tell

Edited to remove a hard-coded Finder reference and a typo.

Thanks a lot Marc Anthony that’s short and to the point. I will test and let you know.

Hi Marc Abnthony,

I tested it and unfortunately I got this error:
error “Finder got an error: Can’t get name of container of every file of every folder of entire contents of folder (alias "Macintosh HD:Users:m:Desktop:old library:").” number -1728 from name of container of every file of every folder of entire contents of folder (alias “Macintosh HD:Users:m:Desktop:old library:”)

This is what I did:
On the desktop I created 2 folders named new library and old library.
Inside old library I have two files: document.wflow, not same doc.wflow and a folder named a. Inside folder a I have 1 file: document1.wflow
Inside new library I have 1 file: document.wflow and a folder named a. Inside folder a I have 1 file: document1.wflow
After running your code I get the error above and in the trash I find 2 files:document.wflow and document1.wflow

Folder a never made it to the trash.
PS: What we need here, I think, is to delete all empty folders in old library regardless of them being in new library.

Yes, it should just delete empty folders and not consider matches, however, it looks like I inadvertently inserted the folder specifier in the second Finder instruction and that oldLibrary’s value is in alias form. Since an alias conflicts with that line’s ending statement, I’ll just coerce it back to a text, which works with the errant specifier. This is technically a little sloppy (unnecessary events), but, considering the meat is only two lines, I’m willing to live with it. :slight_smile:

tell folder (oldLibrary as text)'s entire contents's folders to delete (it whose name is not in (get files's container's name))

Hi Marc Anthony,

Yes that fixed it nicely, thank you.

I met another little problem you might be able to solve -:slight_smile:
I added a second folder to the existing structure of old library: a copy. Inside it I added a document: document1.wflow
That also got deleted because document1.wflow exists in new library although in a different folder, folder a (there is no folder a copy in new library).
I am not sure but I fear that these files need to be left alone, even if double, when they are in a different folder for the library to work ok.
I wander if there is a way to specify: delete all files only if they are in the same folder in both libraries.

Hello, again. I made an attempt at doing this with vanilla Applescript, however, this method will be inefficient with large quantities of files or folders. It seems like you might be better served by using rsync to equalize your folders. Maybe someone else can help you with that or you can search for that topic.


set oldLibrary to (choose folder with prompt "Choose a folder containing items to delete:")
set newLibrary to (choose folder with prompt "Choose a folder containing items to keep:")

tell application "Finder"
	
	set oldECF to (oldLibrary's entire contents's folders whose name is in ¬
		(get oldLibrary's entire contents's folders's name) and name is in (get newLibrary's entire contents's folders's name)) as alias list
	set newECF to (newLibrary's entire contents's folders whose name is in ¬
		(get oldLibrary's entire contents's folders's name) and name is in (get newLibrary's entire contents's folders's name)) as alias list
	
	repeat with counterVar from 1 to count oldECF
		delete (oldECF's item counterVar's files whose name is in (get newECF's item counterVar's files's name))
	end repeat
	
end tell

Thanks Mar Anthony
I ran your code and unfortunately it gave this error:
Finder got an error: Unknown object type.

I tested my last contribution under 10.4.11, Tiger, and it worked as expected. I’m not sure where it might be hanging, and I don’t have access to a later version of the OS to find an answer.

Thanks for that explanation Marc Anthony,

With that in mind I modified it to the following which works 100% in Lion 10.7.2.
Thanks for your patience and help.


(* compare any two folders, delete all files in oldLibrary with the same name in newLibrary but only if they both are in a folder with the same name and delete all empty folders in oldLibrary.*)
set oldLibrary to (choose folder with prompt “Choose a folder containing items to delete:”)
set newLibrary to (choose folder with prompt “Choose a folder containing items to keep:”)
tell application “Finder”
set oldECF to (oldLibrary’s entire contents’s folders whose name is in (get oldLibrary’s entire contents’s folders’s name) and name is in ((get newLibrary’s entire contents’s folders’s name) as list))
set newECF to (newLibrary’s entire contents’s folders whose name is in (get oldLibrary’s entire contents’s folders’s name) and name is in ((get newLibrary’s entire contents’s folders’s name) as list))
repeat with counterVar from 1 to count oldECF
delete (oldECF’s item counterVar’s files whose name is in (get newECF’s item counterVar’s files’s name))
end repeat
tell folder oldLibrary’s entire contents’s folders to delete (it whose name is not in (get files’s container’s name))
end tell