I want to list all files in my home directory and subdirectories in order of date modified. In other words, if file foo in directory A was most recently modified, and file bar in directory B was second most recently modified, then I would like those two files listed consecutively. If there is an easy way to do this only for files modified since Sep 22, that would be even better. I do not need to know what directory holds the file; I’ll be able to figure that out from the leafname (and if I can’t, I can search). Many thanks. (If anyone cares, I took one computer on a trip, and I want to find all the files that I edited on that trip.)
The command line solution is to use find to filter the files, and pipe that to ls. *
But I’m going to be that guy and suggest that this is a perfect use case for Thomas Templemann’s excellent Find Any File. It can process a directory and its sub-directories, filter for files modified on or after a specific date, sort the output list by date.
You can chose the see the results as a flat list, or in a tree by location – even sorted overall by date!. And, you can act on the results in the list. QuickView, copy, whatever.
You can try it out without buying first.
* As @blm explains below, this is wrong. I just did a quick search and looked at a Stack Overflow post but didn’t look closer, because I was going to suggest FAF anyway.
Thank you. I do plan to look at Find Any File, but I also want to understand find and your command line solution. If I set my working directory to ~/Documents and then run find . -newer “case file” (where “case file” is the oldest file I want to find), I think I get the results I want. If I run that command and pipe the results to ls, I get a listing of Documents, including files older than “case file”, and no files from subdirectories. What did I do wrong?
ls doesn’t read the files to list from standard input, it gets them from its command line. So in find . -newer "case file" | ls, find produces the list of files (and directories) on its standard output, which is connected to ls’s standard input, which ls blithely ignores and, being it wasn’t told what to list, lists the current directory.
You could do something like this:
ls -lt $(find . -type f -newer "case file")
What that does is run find, finding files (only) which are newer than “case file”. The shell collects find’s output, and adds it to ls’s command line.
That has (at least) two problems though. The first is it won’t deal with file paths with spaces in them correctly. The second is that the length of a command line is limited, so if find finds lots of files, that will fail.
Personally I’d just write a little perl script (maybe even a one-liner) which reads file paths from standard input, looks up their modification dates, sorts them by that, and then prints them, but that requires perl (or some other scripting language) knowledge.
Or you could use Find Any File ![]()
Claude says to use -newer with a reference file, should combine with stat for sorting. Reason is that method works for all find criteria: -newer, -newermt, or any others.
find . -type f -newer "/path/to/somefile" -exec stat -f "%Sm %N" -t "%Y-%m-%d %H:%M:%S" {} + | sort
It is assuming you’re in the starting directory.
So what we have here, I think is:
- find . is starting in current directory
- -type f means find files, not directories
- -newer you know
- -exec is executing a command for each file found, passing it the filename at the {}.
- the stat -f parameter says to output a custom format, which is the modification time and the file name/path
- the stat -t parameter says how to format the timestamp
- The + is terminating the exec, but saying to batch all the found file names and send them to stat all at once. That’s more efficient than executing stat once per file.
- pipe it to a sort
- and Bob’s your uncle
To deal with spaces, you can generally just apply quotes to the parameters. Use double-quotes ("), so the shell will still expand the contents. And since you can’t nest identical quotes, use single-quotes (') for the inner quoted text:
ls -lt "$(find . -type f -newer 'case file')"
To deal with line-lengths, that’s what the xargs command is good for. And if you use that, it can also deal with spaces in file names:
find . -type f -newer "case file" -print0 | xargs -0 ls -lt
The -print0 option tells the find command to separate found filenames with NULL characters (byte value 0) instead of spaces.
The xargs command reads a list of file names, breaks the list into groups of filenames (5000 per group by default) and calls the associated command once for each group. The -0 option tells it to use NULL characters instead of spaces as the delimiter between files.
So, the above command-line will call the find command, as you wrote, to produce a list of filenames. It will then pipe that entire list to the xargs command using NULL bytes as delimiters (so spaces in filenames won’t break anything) and call ls -lt with that list of filenames, calling it multiple times if the set of files found is too large for a single command-line.
Note that find has an option -ls which basically produces an ls-like listing of all the files found.
Good point, I should have thought of that, although getting quoting right in a shell is hard enough I usually just switch to some scripting language if I get to that.
find . -type f -newer "case file" -print0 | xargs -0 ls -lt
Yes, I’ve used find and xargs together many times. But I don’t think it will work in this particular case. @Will_M wants all the newer files sorted together. If xargs has to use more than one chunk, then only the files in each chunk will be sorted, the chunks won’t be sorted together. So if, for example, the second chunk contains the most recently modified file, it will appear first in that chunk, but after all the files in the first chunk. xargs will only work if the total characters in all the paths find outputs fit in one chunk, in which case you don’t really need xargs.
It does, but I don’t think it does any kind of sorting. You may be able to pipe it to sort though with whatever arguments are needed to sort find’s ls output by modified date.
This is probably the way to go.
Thank you all. I should have mentioned that I expected there to be only a few files, under a dozen. I wanted them bunched at one end of the output (top or bottom, didn’t matter) so I wouldn’t need to sift through the many directories. However, find -newer (with appropriate arguments) solved that problem. In the end, if I did it correctly, there were only three files that I modified on the local disk of the travel computer. Since I remembered changing those three, and I set the search parameters to cover more time than I needed, I believe I captured them all.
Thanks especially to @mschmitt for the detailed explanation (I don’t recall using + like that before), and now Bob is my uncle.
NCDU, but you will have to create a config file to get it to display in color or use a flag/
You can easily install it with Brew
You can also do this with Finder. I do it frequently.
Show only files modified in the last week (or whatever time period), use column headers to sort, limit to the current folder and all sub folders.
Similar to the suggestion of Find Any File app, in the first response.
For the record I use an app called Houdah Spot which I think does everything that Find Any File does—though I concede it is a lot more expensive!
Thank you. I thought I understood what you meant, but after trying it, I’m sure I don’t.
How do I limit the view to files modified since a date? When you say “limit to the current folder and all sub folders”, do you mean by using List View and expanding subfolders? Thanks.
Finder searches sub-folders by default, you can’t get it not to.
So I go into the folder that is the highest level I want to search. eg. Project folder
I type “week” in the search box and then choose “this week”. You can type any date or timestamp in there.
Then sort by Last Modified column
(you might need to right click the column header to toggle that column as visible)
Thank you.
Would the search field accept a date range, like Sep 24 to Nov 05? I couldn’t figure out how to do that.
Perhaps I should have led with this, but what macOS are you using? I just tried it on a Mac running Sequoia, but the Mac at the start of this thread is running Big Sur.
Here’s an oddity for anyone who is interested. If I type 10 (like is shown in your screenshot), the Finder happily offers to interpret it as 10:00 AM today. But if I type 10 PM, the Finder offers to interpret it as 10:00 AM. If I type 22, the Finder offers to interpret it as the 22nd of last month. If I type 10:00 PM, the Finder offers to interpret it as text. I need to type 22:00 to get 10 PM.
You can type:
- date:12/20/2022-01/02/2023 AND kind:image
Or use the Finder search creator:
I’m on Seqouia,but this has been in macOS for decades.
And I’ve managed to ignore it for decades. Thanks for pointing this out. It does seem like the simplest solution to my original problem.



