List Folders Older Than 30 Days

Does anyone have an existing script that will look at a specific folder, with many subfolders, and create a list of those folders that are more than 30 days old or older?

I actually have a script (below) that was created here that will list documents older than 7 days, but no matter what I try to do, I can not convert it to folders.

use framework "Foundation"
use scripting additions

on main()
	set theFolder to "/Users/homer/Documents"
	set theDays to 7 --set to desired value
	set theFiles to getFiles(theFolder, theDays)
	set folderTree to getFolderTree(theFiles)
	writeFile(folderTree)
end main

on getFiles(theFolder, theDays)
	set fileManager to current application's NSFileManager's defaultManager()
	set theFolder to current application's |NSURL|'s fileURLWithPath:theFolder
	set dateKey to current application's NSURLContentModificationDateKey
	set directoryKey to current application's NSURLIsDirectoryKey
	set packageKey to current application's NSURLIsPackageKey
	set folderContents to (fileManager's enumeratorAtURL:theFolder includingPropertiesForKeys:{} options:6 errorHandler:(missing value))'s allObjects() --option 6 skips hidden files and package contents
	set filterDate to current application's NSDate's dateWithTimeIntervalSinceNow:(-86400 * theDays)
	set theFiles to current application's NSMutableArray's new()
	repeat with anItem in folderContents
		set {theResult, aDate} to (anItem's getResourceValue:(reference) forKey:dateKey |error|:(missing value))
		if (aDate's compare:filterDate) = 1 then --1 is NSOrderedDescending
			set {theResult, aDirectory} to (anItem's getResourceValue:(reference) forKey:directoryKey |error|:(missing value))
			if (aDirectory as boolean) is false then
				(theFiles's addObject:anItem)
			else
				set {theResult, aPackage} to (anItem's getResourceValue:(reference) forKey:packageKey |error|:(missing value))
				if (aPackage as boolean) is true then (theFiles's addObject:anItem)
			end if
		end if
	end repeat
	if theFiles's |count|() = 0 then display dialog "No matching files found" buttons {"OK"} cancel button 1
	set pathDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:"stringByDeletingLastPathComponent" ascending:true selector:"localizedStandardCompare:"
	set nameDescriptor to current application's NSSortDescriptor's sortDescriptorWithKey:"lastPathComponent" ascending:true selector:"localizedStandardCompare:"
	return ((theFiles's valueForKey:"path")'s sortedArrayUsingDescriptors:{pathDescriptor, nameDescriptor})
end getFiles

on getFolderTree(theFiles)
	set fileTree to current application's NSMutableArray's new()
	set previousFolder to (theFiles's objectAtIndex:0)'s stringByDeletingLastPathComponent()
	fileTree's addObject:(previousFolder's stringByAppendingString:"/")
	repeat with aFile in theFiles
		set aFolder to aFile's stringByDeletingLastPathComponent()
		set aFileName to aFile's lastPathComponent()
		if (aFolder's isEqualToString:previousFolder) is false then
			(fileTree's addObject:"")
			(fileTree's addObject:(aFolder's stringByAppendingString:"/"))
			(fileTree's addObject:aFileName)
		else
			(fileTree's addObject:aFileName)
		end if
		set previousFolder to aFolder
	end repeat
	return ((fileTree's componentsJoinedByString:linefeed) as text)
end getFolderTree

on writeFile(theText)
	set pdfMargins to 25
	set targetTextFile to ((current application's NSTemporaryDirectory())'s stringByAppendingPathComponent:"Recent File Changes.txt") as text
	set targetPdfFile to (((current application's NSHomeDirectory())'s stringByAppendingPathComponent:"Desktop")'s stringByAppendingPathComponent:"Recent File Changes.pdf") as text
	(current application's NSString's stringWithString:theText)'s writeToFile:targetTextFile atomically:true encoding:(current application's NSUTF8StringEncoding) |error|:(missing value)
	do shell script "cupsfilter -D -o page-left=" & pdfMargins & " -o page-right=" & pdfMargins & " -o page-top=" & pdfMargins & " -o page-bottom=" & pdfMargins & " " & quoted form of targetTextFile & " > " & quoted form of targetPdfFile
end writeFile

main()

On any volume indexed by Spotlight it’s pretty convenient to search for the items with mdfind

set inputFolder to quoted form of POSIX path of (choose folder)
set foundFolders to paragraphs of (do shell script "mdfind -onlyin " & inputFolder & " 'kMDItemKind = \"Folder\" && kMDItemContentCreationDate < $time.today(-30)'")

The search criteria are

  • the kind (kMDItemKind) is Folder
  • the creation date (kMDItemContentCreationDate) comes before today - 30 days ($time.today(-30))

The result in foundFolders is a list of POSIX paths.

For the modification date use kMDItemContentModificationDate or kMDItemFSContentChangeDate.

What do you mean by older than 30 days.

Last time access, date created, date modified etc?

1 Like

Good point. There are Spotlight specifiers for all occasions.

Unless the number of folders is quite large, you can do what you want with Finder. The script in your post uses modification date and the same is used in the following:

set theFolder to (choose folder)
set archiveDate to (current date) - 30 * days

set oldFolders to {}
tell application "Finder"
	set theFolders to every folder of the entire contents of theFolder as alias list
	repeat with aFolder in theFolders
		set folderDate to modification date of aFolder
		if folderDate is less than archiveDate then set end of oldFolders to (aFolder as text)
	end repeat
end tell
 
return oldFolders

Seeing how I’m going to be looking at folders created by backup programs, I would think date created (probably should have included that bit of information).

I have a script that is pure AppleScript

local sw, c, cf, i, folderPaths, modDates, oldDate
tell application "System Events"
	set {folderPaths, modDates} to {path, modification date} of folders of folder "/Users/Homer/Desktop/MacScripter Files/"
	set cf to count folderPaths
	set c to 1
	set oldDate to ((current date) - 30 * days)
	repeat with i from 1 to cf
		if (item i of modDates) ≥ oldDate then
			if i ≠ c then
				tell modDates
					set sw to item i
					set item i to item c
					set item c to sw
				end tell
				tell folderPaths
					set sw to item i
					set item i to item c
					set item c to sw
				end tell
			end if
			set c to c + 1
		end if
	end repeat
	if c > 1 then
		set modDates to items c thru -1 of modDates
		set folderPaths to items c thru -1 of folderPaths
	else if c > cf then
		set modDates to {}
		set folderPaths to {}
	end if
end tell
get {modDates, folderPaths}

The path is in folderPaths, the date modified is in modDates

I copied my MacScripter Files folder to the desktop and first tried the script posted by StefanK in post #2, and then changed peavine’s script in post #5 from “modification date” to “creation date” and both scripts found the same 12 folders that were older than 30 days. Thanks guys.

Could not figure out how to get your script to select the “MacScripter Files” folder that I copied to the Desktop. Where would I insert the path, which is “Users/Homer/Desktop/MacScripter Files”?

I fixed it for you above.

Since you are using POSIX paths instead of HFS paths

You can use the shell’s find command.

% find '/Users/homer/Documents' -type d -depth 1 ! -Btime -30

The above breaks down as follows:

find '/Users/homer/Documents'’ means ‘find within the specified directory’. Alternatively, you could set it as a variable or could change the shell’s working directory.

-type d’ restricts the results to directories. You can also use ‘f’ to specify files; there are some other less obvious types as well.

-depth 1’ restricts the results to those in the top directory of the search. If you wish to generate results from subdirectories, then increase the number accordingly or remove the option entirely.

! -Btime -30’ has three components.

  • The ‘B’ at the beginning of ‘Btime’ means check the creation time. You can also look for the last modified time using ‘mtime’. Note that this option is case sensitive.

  • The ‘-30’ means 30 days. Normally, the option ‘-Btime -30’ would list results created within the last thirty days

  • The preceding ‘!’ reverses that to not within the last thirty days.

Here is how an applescript might look, assuming the Documents folder:

use scripting additions
set cmd to "find '/Users/homer/Documents' -type d -depth 1 ! -Btime -30"
set older30 to do shell script cmd