I’m trying to delete a large number of messages from Mail.app using AppleScript. I’ve been able to identify the messages and get them into a list, but I’m having trouble deleting them efficiently. Right now, I’m looping through the list as follows:
tell application "Mail"
repeat with msg in toDelete --This is the list of messages.
delete msg --or: move msg to mailbox "Trash"
end repeat
end tell
This works perfectly (whether I delete or merely move to Trash), but it takes about 0.6s per message—fast enough if I’m deleting 10-20 messages, but not so much if I’m deleting 10,000-20,000.
I’ve read that AppleScript should be able to move a list of messages all at once, but I can’t seem to get it to work. Any ideas?
Hi. Putting messages in a variabilized list dereferences them and necessitates looping, and iterating through 20K items takes however long it takes. You could use a whose clause—which has its own time overhead to filter the items—or just specify by range to affect multiples. This assumes the account is the only or the first:
Thanks, Fredrik. I also love Smart Mailboxes, but it never occurred to me to use them in this way. Is there a way to create a smart mailbox that would show all but one of every set of duplicates?
It will not be possible to create a useful smart mailbox to display only originals.
It is much easier to let the script mark the duplicates with some colored flag. Then you can see with your own eyes in the message viewers which messages are flagged and delete them at your discretion. Most duplicates are usually found in the “Archive” mailbox.
The following script marks duplicates in Green. Then, you create manually smart mailbox with condition “Message has flag” , where you can select all its contents and delete at once, or one by one.
set {IDs, Duplicates} to {{}, 0}
tell application "Mail"
repeat with anAccount in (accounts)
repeat with aMailbox in (mailboxes of anAccount)
try
set aMessages to messages of aMailbox
repeat with aMessage in aMessages
set aMessageID to id of aMessage
if (IDs contains aMessageID) then
set flag index of aMessage to 3 -- Green color
set Duplicates to Duplicates + 1
else
set end of IDs to aMessageID
end if
end repeat
end try
end repeat
end repeat
end tell
display dialog "---- " & Duplicates & " Duplicate Messages Flagged with Green ----"