17

How do I list all files under a directory recursively and sort the output by modification time?

I normally use ls -lhtc but it doesn't find all files recursively. I am using Linux and Mac.

ls -l on Mac OS X can give

-rw-r--r--    1 fsr  user      1928 Mar  1  2011 foo.c
-rwx------    1 fsr  user      3509 Feb 25 14:34 bar.c

where the date part isn't consistent or aligned, so a solution have to take this into account.

Partial solution

stat -f "%m%t%Sm %N" ./* | sort -rn | head -3 | cut -f2-

works, but not recursively.

1
  • I'm going to assume you are on Linux, but you should specify your OS explicitly either in the question or preferably in as a tag.
    – EBGreen
    Apr 24, 2012 at 18:44

5 Answers 5

2

Here is a method using stat as @johnshen64 suggested

find . -type f -exec stat -f "%m%t%Sm %N" '{}' \; | sort -rn | head -20 | cut -f2-
3
  • find "$PWD" -type f -exec stat -f $'%m\t%N' '{}' \; | sort -rn | cut -f2- would print just the absolute paths of the files on OS X.
    – Lri
    Apr 26, 2012 at 9:04
  • 3
    which version of stat are you using? your format above didn't work for me. I had to use the following: find . -type f -exec stat --printf "%Y\t%y %N\n" '{}' \; | sort -rn | cut -f2-. This is with stat (GNU coreutils) 8.23
    – user84207
    Sep 4, 2017 at 2:23
  • 2
    This solution no longer works - it has multiple errors with regards to modern "stat" commands. Or worse, even if fixed, it is slow - it invokes the external "stat" command for each file. On my machine, this can easily take a full second for 1000 files. The better solution is below, using find's "-printf" option, is at least 100 times (!) faster. Jun 29, 2020 at 11:23
14

Use find's -printf and sort on a reasonable date format:

find -type f -printf '%T+\t%p\n' | sort -n

This should minimize process forks and thus be the fastest.

Examples if you don't like the fractional second part (which is often not implemented in the file system anyway):

find -type f -printf '%T+\t%p\n' | sed 's/\.[[:digit:]]\{10\}//' | sort -n
find -type f -printf '%T+\t%p\n' | cut --complement -c 20-30 | sort -n

EDIT: Standard find on Mac does not have -printf. But it is not difficult to install GNU find on Mac (also see that link for more caveats concerning Mac/Linux compatibility and xargs).

1

find . should be able to get all the files. Something like this:

find . -exec ls -dl '{}' \; | sort -k 6,7

You need to tune it for you needs.

6
  • i also assume it is linux, like EBGreen said, ls is an alias in windows PS so you need to use sort-object and get child items recursively if that is the case but the idea is the same.
    – johnshen64
    Apr 24, 2012 at 18:53
  • Does it really work correctly when the dates sometimes misses the year part, on Mac?
    – qazwsx
    Apr 24, 2012 at 19:10
  • you are right, the date display for recent files will mess up things. you need to use stat instead to get the exactly formatted date in that case. my files are all very old so the command worked fine, that is why i added the tune clause :-)
    – johnshen64
    Apr 24, 2012 at 19:16
  • @johnshen64: ls on Linux has a --time-format option you can use to ensure that both recent and older file dates are shown in the same format. Apr 24, 2012 at 19:46
  • ah thanks, you are right, just have not used that. that is much simpler than using stat. it is called --time-style i think.
    – johnshen64
    Apr 24, 2012 at 21:30
1

This answer to a similar question on the Unix Stack Exchange site helped me because I was using zsh:

How to list files sorted by modification date recursively (no stat command available!)

1
0

On my Linux, it required a small tweak using stat because of coreutils:

find . -type f -exec stat -c "%y %N" "{}" \;

To find the most recent 20 files, sort reverse order by modification time:

find . -type f -exec stat -c "%y %N" "{}" \; | sort -rn | head -20 | cut -f2-

From stat (manual) docs:

%y - Time of last modification
%Y - Time of last modification as seconds since Epoch
%n - File name
%N - Quoted file name with dereference if symbolic link

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.