How to sort Download folder into subfolders by date

Ladies and gentlemen,

I'm a moderately competent KeyboardMaestro user of many years. I mostly use KeyboardMaestro to create missing keyboard shortcuts and change existing ones. I also use the app switcher to make sure that my app switcher is on the monitor where the mouse is (Apple's app switcher inexplicably defaults to the primary monitor).

Now I have something more complex. How can I sort my download folder into dates with KeyboardMaestro? I'm sure it's possible but just over my head as I don't usually use the file manipulation tools.

I used to use Hazel 4 for this but since this is the only use I have for Hazel, I would like to do this with KeyboardMaestro which is on my long term maintain/upgrade list. With frequent paid upgrades (necessitated by Apple continuously moving the cheese for developers), I'm working to cut back on the amount of software I use (too much).

The idea is that by running the macro all new files in Downloads would be sorted into folders like


Ideally the existing folders with names in that pattern (yearmonthdate) would be ignored so it could run on Downloads without having to move the files somewhere else. It would be okay to move them somewhere else if it would make the macro much simpler.

If anyone has an existing similar macro, I'd be very grateful if you'd share. If this is a duplicate post, please point the way to the original and I'll take the instructions from there.

Thanks, Alec

Edit: Please see my post below for a much better version. This first one was not good at all.



Rob, thank you so much. Your script works a treat. The outbound filenames need some tweaking as they duplicate the folder names with a question mark in the middle. Example:


KeyboardMaestro has always been brilliant (I'm a Peter Lewis fan going all the way back to Anarchie). It turns out the community is as splendid as the application.

That's odd; it worked perfectly here, creating the folders exactly as you specified. Can you do me a favor, and add a Display Text in a Window step right after the shell script mdls one? You'll get one window per file, so just add one file to Downloads then run the script. Copy and paste what's in that window back here so I can check my regex against your output.


Hi Rob. Thanks for the quick answer.

You're asking a lot (I was over my head with your shorthand answer) but believe I did figure it out. I was hunting a specific variable and needed to use Display Text in Window finally. Here's the output.

kMDItemDateAdded                       = 2023-12-13 20:50:19 +0000
kMDItemDateAdded_Ranking               = 2023-12-13 00:00:00 +0000

What doesn't kill you, makes you stronger.

Sorry, didn't mean to be shorthanded about it :). I was just trying to tell you to make it look like this:

And then to run the macro after adding a single file, and send me the output that's in the text window. But you figured that out :slight_smile:

And I think I see the problem, as there's a second line in your output that's not in mineβ€”I don't have a ranking line. Lemme mess with the regex just a touch, posting again soon.


It's probably time I learned to use KeyboardMaestro better. I agree with you about hidden interface btw. Absolutely diabolical. Better pale, or a single symbol or something to hint to the user to click around the area.

Yep, anything to let us know there's something there :).

Edit the "Get the date the item was added to Downloads" action in the macro I attached above, and change the shell script text bit to this:

mdls "$KMVAR_local_theFilename" | grep kMDItemDateAdded\

NOTE: There's a backlash-space at the end, not just a backslash!

This forces the grep to only find the line that has a space immediately after "Added," which should fix the folder name issue.


Hi Rob,

Thanks for the update.

Not working too well. Still creating the funny double date file names (I've updated to KeyboardMaestro 11 just in case it was a difference between 10 and 11).

Moreover it's difficult to test as once the files are moved, they can't be moved back and then tried again. You are getting the kMDItemDateAdded. If it's possible to get the date downloaded, that would make testing easier (as then files would sort again after being put back into /Downloads Right now when resorting all the files get dumped into the current date.

This is not an issue for production as one would only sort by date once.

What is a worry is that the folders also get moved whenever the macro is run on /Downloads . Here's the staring point.


Here's the result:


It would be easier to use the macro if there was a filter to exempt properly named folders (yearmonthdate or 20231214). The way it's set up currently is that after sorting all the created folders have to be moved away.

I can of course clean up the existing folder names with software like Name Mangler. There are two issues

  1. is to name the folders properly at some point.
  2. include a filter to avoid nesting already sorted folders in the current date run

We are so close.

I'll take a look at it - thanks for the detailed report.


1 Like

OK, as with most things I do here … version two is so much better than version one that version one never should have existed :).


Move downloads to date-based folders.kmmacros (29 KB)

Screenshot of the macro


This version has the following features:

  • Now acts on Date Downloaded, which I didn't even realize was a viable Spotlight field. This makes it easy to undo and redo filing, as you can move things back to the top level, and the macro will then happily move them back to the right spot.

  • User-settable YYYY MM DD separator, including no separator. (I added this because I prefer a separator, and testing it without one was driving my OCD crazy :slight_smile: ). Please read the note on the macro about this, as if you later change your delimiter, you'll have to do a bit of work on your own (see next bullet).

  • The macro won't try to move any folders that match its naming convention, for two reasons. First, I skip them based on a regex match. But if that fails, they also don't have a downloaded date field, so they won't move anyway. (See above, though: If you change the delimiter, the regex check will fail for existing folders, so they'll constantly show up in the next bullet's output, unless you rename them.)

  • Not every downloaded file gets the downloaded date metadata. Things transferred from your phone or via AirDrop, for instance. (I also noticed it on a couple files I did download from the web, so I'm not sure of the cause.) The macro tracks these files, and shows them in an end-of-run dialog:

  • There's a progress bar during filing operations, just so you know the macro's doing something.

  • End-of-run logic makes sure that all cases are covered: files that moved, files that can't move, no files to move.

Please give this one a shot, and let me know how it goes; it's working quite well here in testing.


Hi Rob,

This is certainly a much more robust version. I didn't realise the download date is Spotlight data only. I'm not sure I had Spotlight running on this drive at the time of the downloads. Just tested Spotlight search, it still doesn't find files I know are there.

Here's the error I received (great that there's built-in errors now):


The full list is much, much longer. Everything lacked the "downloaded date" metadata.

I'm rebuilding my Spotlight index now sudo mdutil -E /

I'll let you know if that fixes the issue. Alternatively there would have to be another way to detect the download date. Not sure if alternative access to that data is built into KeyboardMaestro. It would be more robust not to assume Spotlight.

As far as I know, download date is only easily available via macOS metadata (I.e. Spotlight). The alternative would be to use date added, as before, as that’s intrinsic to the system and not metadata.

But as you know, that means you can’t easily undo what’s done.

The only other place I can think to look would be in the Finders Get Info window. But if anything is there it’d be hard to get to. I’ll check later at home.


Spotlight is reading the download date from somewhere. My guess is that via AppleScript it should be possible to get the download date. I'll try a test with less files shortly.

I don't think you'll find anything, but I did some more digging this morning and I don't think it matters :). I ran a test in Firefox, and found it doesn't get the download date metadata, so that's a Safari-only thing.

So I went looking, and found a much better metadata field to use: kMDItemFSCreationDate

That's the date the filesystem created the file, and it should exist even without Spotlight being enabled. And you can move stuff into and out of the datestamped folders and they'll re-sort properly. It's a much better proxy for download date than the actual download date metadata field.

Try this version of the macro:

Move downloads to date-based folders.kmmacros (28 KB)

Let me know how that works for you. On my system, it moved all the files easily.


1 Like

Perfect. Here's what the folder looks like now:

I ran it again now with some new files in Downloads and again your macro worked perfectly, filing the new files and leaving alone the existing folders.

Thanks so much Rob.

PS. I'm sorry not to get back to you right away. I had the screenshot ready and this post half-written on Friday but wanted to run another test and the post did not get sent you. I can't express how wonderful it is to have this functionality back and within KeyboardMaestro. This macro to sort downloads is useful enough that perhaps @peternlewis might want to feature it in a newsletter or in a weblog post.

What's very nice about the way you wrote the macro is that there are quite a few very useful steps properly documented, so this macro could serve as the basis for quite a few file sorting and file management macros, and to teach others how to write more sophisticated KeyboardMaestro macros.

1 Like

Glad it's working for you. I replaced the macro this morning (in the above post) with a very slightly modified version that simplifies how I extract the date. Other than that, it's identical to the previous version.

No problem, it was a fun one to work through.

I mostly do that for myself, so I remember what I'm doing :).