Folder script to delete files above a specific count

Hello Mavens,

Likely it is a simple thing: I would like a folder to autodelete the file that was added to it the longest time ago if the count of the files is above a certain number, let’s say 10.

Could you give suggestions?

Thanks

If I were doing this I would use Shane’s Filemanagerlib.script.

With that you can get loop through the files getting the date_added property of each one, and then delete the oldest.

Freeware | Late Night Software
FileManagerLib v2.3.5

FileManagerLib provides commands for file management tasks like duplicating, copying, moving, renaming, deleting, and trashing files, as well as creating folders and alias files, getting the contents and entire contents of folders, and sorting lists of files. Version 2.3.x adds comparison commands and commands for dealing with date properties. (updated May 27, 2020)

Thanks, looks really cool!

AsuMasu. The following script should do what you want. To delete files automatically, you have to set up the script as a folder action, which is described here. I’ve never created a folder action and can’t help with that. The following script moves files to the trash, but still please test carefully.

use framework "Foundation"
use scripting additions

set retainCount to 10 -- number of files to retain
set theFolder to POSIX file "/Users/Robert/Downloads/" -- set to desired path
tell application "Finder" to set theFiles to (every file in folder theFolder) as alias list
set sortedFiles to getSortedFiles(theFiles)
set sortedFilesCount to (count sortedFiles)
if sortedFilesCount > retainCount then
	set deleteList to {}
	repeat with i from 1 to (sortedFilesCount - retainCount)
		set end of deleteList to POSIX file (item i of sortedFiles)
	end repeat
	tell application "Finder" to delete deleteList
end if

on getSortedFiles(theFiles)
	set pathKey to current application's NSURLPathKey
	set dateKey to current application's NSURLAddedToDirectoryDateKey
	set theFiles to current application's NSArray's arrayWithArray:theFiles
	set sortedFiles to current application's NSMutableArray's new()
	repeat with aFile in theFiles
		(sortedFiles's addObject:(aFile's resourceValuesForKeys:{pathKey, dateKey} |error|:(missing value)))
	end repeat
	sortedFiles's sortUsingDescriptors:{current application's NSSortDescriptor's sortDescriptorWithKey:dateKey ascending:true}
	return (sortedFiles's valueForKey:(current application's NSURLPathKey)) as list
end getSortedFiles
1 Like

This works perfectly, thank you!

AsuMasu. I’m glad that worked.

I rewrote the above script for my personal use and have included it below FWIW. The timing results with a folder containing 15 files were 69 milliseconds for the earlier script and 6 milliseconds for the new script. This is with the Foundation framework in memory.

use framework "Foundation"
use scripting additions

set theFolder to "/Users/Robert/Downloads/"
set fileManager to current application's NSFileManager's defaultManager()
set theFiles to getFiles(fileManager, theFolder)
set sortedFiles to getSortedFiles(theFiles)
trashOldFiles(fileManager, sortedFiles, 10) -- 10 is the number of files to retain

on getFiles(fileManager, sourceFolder)
	set sourceFolder to current application's |NSURL|'s fileURLWithPath:sourceFolder
	set regularFileKey to (current application's NSURLIsRegularFileKey) -- does not include packages
	set folderContents to fileManager's contentsOfDirectoryAtURL:sourceFolder includingPropertiesForKeys:{} options:4 |error|:(missing value) -- option 4 skips hidden files
	set theFiles to current application's NSMutableArray's new()
	repeat with anItem in folderContents
		set {theResult, aRegularFile} to (anItem's getResourceValue:(reference) forKey:regularFileKey |error|:(missing value))
		if aRegularFile as boolean is true then (theFiles's addObject:anItem)
	end repeat
	return theFiles
end getFiles

on getSortedFiles(theFiles)
	set pathKey to current application's NSURLPathKey
	set dateKey to current application's NSURLAddedToDirectoryDateKey
	set sortedFiles to current application's NSMutableArray's new()
	repeat with aFile in theFiles
		(sortedFiles's addObject:(aFile's resourceValuesForKeys:{pathKey, dateKey} |error|:(missing value)))
	end repeat
	sortedFiles's sortUsingDescriptors:{current application's NSSortDescriptor's sortDescriptorWithKey:dateKey ascending:true}
	return (sortedFiles's valueForKey:(current application's NSURLPathKey))
end getSortedFiles

on trashOldFiles(fileManager, theFiles, retainFileCount)
	if (theFiles's |count|()) > retainFileCount then
		repeat with i from 0 to ((theFiles's |count|()) - retainFileCount - 1)
			set aFile to (current application's |NSURL|'s fileURLWithPath:(theFiles's objectAtIndex:(i)))
			(fileManager's trashItemAtURL:aFile resultingItemURL:(missing value) |error|:(missing value))
		end repeat
	end if
end trashOldFiles

Thank you, these are great scripts. BTW I used your first script in Filemaker and I had to enclose the “if” statement between “tell app Finder” / “end tell”, otherwise it gave an error message at the word “ascending”.

1 Like