109

I want to use find but sort the results reverse chronologically as with ls -ltr. Is this possible through any combo of flags or pipelines?

dan
  • 4,007
  • 5
  • 26
  • 34
  • 1
    Best way is 'find -exec ls -ltr {} +'. – gaoithe Mar 07 '17 at 13:45
  • 4
    @gaoithe That works only up to a certain number of files. Beyond that, the files will be split in batches. – Dennis Mar 16 '17 at 01:09
  • 2
    Voting to reopen because https://unix.stackexchange.com/questions/20611/list-files-larger-than-size-sorted-by-date wants only in current directory "and subdirectories, which I don't want". – Ciro Santilli OurBigBook.com Apr 08 '19 at 10:19
  • Yeah, this isn't a duplicate at all. Even the answers of the two questions are distinct. – Wayne Conrad Jun 04 '20 at 13:51
  • To find **all files on disk** sorted by date, I use `sudo find / -printf "%T+ %p\n" | grep -v "/proc/" | grep -v "/sys/" | sort | less +G` (I remove `proc` and `sys` on purpose here). – Basj Sep 14 '21 at 07:52

2 Answers2

161

Use find's -printf command to output both the time (in a sortable way) and the file, then sort. If you use GNU find,

find . your-options -printf "%T+ %p\n" | sort

For convenience here is an explanation of the -printf "%T+ %p\n" from man find:

  • %Tk File's last modification time in the format specified by k, which is the same as for %A.
    • where k in this case is set to +
    • + Date and time, separated by +, for example `2004-04-28+22:22:05.0'. This is a GNU extension. The time is given in the current timezone (which may be affected by setting the TZ environment variable). The seconds field includes a fractional part.
  • %p File's name.
angus
  • 12,131
  • 3
  • 44
  • 40
  • 8
    `sort -r` for reverse order. – stnly Jan 24 '12 at 15:12
  • 9
    `ls -t` sorts newer to older, `sort` sorts older to newer. So `ls -t`'s reverse order is `sort`'s normal order. – angus Jan 24 '12 at 15:19
  • 1
    Do you have a version for OS X (non-gnu)? – Ortomala Lokni Aug 25 '16 at 15:48
  • 1
    @OrtomalaLokni No, sorry. Looking at the [man page](http://ss64.com/osx/find.html) I'd say it would entail using the `-ls` argument and then `cut` (or `awk`) to extract the desired fields.... but better ask a new question about it, and somebody will come up with a complete answer. – angus Aug 25 '16 at 17:13
  • This does not work if you're using `-or ` to combine multiple iname options in find. The -printf only prints the results of the last ORed condition. Any thoughts on how to work around that? – SSilk Jan 03 '17 at 15:04
  • 6
    For OS X and non-GNU, use [this answer](http://superuser.com/a/546900/365890). – Tom Hale Jan 11 '17 at 04:46
  • @SSilk Group your expression: `find . your-options \( your-expression \) -printf "..." | sort`. – angus Jan 11 '17 at 13:51
  • Dont work in non-GNU or other distributions... -1 – Brethlosze Nov 28 '17 at 20:36
  • 8
    To get this to work with OSX, install findutils from homebrew, then use gfind not find. https://stackoverflow.com/questions/752818/find-lacks-the-option-printf-now-what – Chris Mar 05 '18 at 00:44
  • 1
    @TomHale didn't work on my 10.12.6: find: -printf: unknown primary or operator – Neithan Max Feb 13 '19 at 13:21
  • suspicious result: `1985-10-26+09:15:00.0000000000 app/react/node_modules/abab/CHANGELOG.md` (Ubuntu 18.04.3 LTS, find (GNU findutils) 4.7.0-git) – webb Jun 10 '20 at 11:15
  • And to get the filename of the lastest file: `find YOUR-OPTIONS -printf '%T+\t%p\n' |sort -r |head -1 |cut -s -f2` – EM0 Feb 02 '21 at 16:02
5

If that is just a depth-n (assume depth-2) folder hierarchy, I find this one useful:

ls -laht --full-time */*
Ben Usman
  • 189
  • 2
  • 7
  • This seems to produce a list of files that are exactly two folders deep (no more, no less), along with separate listings of each of the folders that are exactly two folders deep. – mwfearnley Feb 12 '17 at 13:42
  • 2
    @mwfearnley that is exactly what I meant by "that is just a depth-n" above :) you can do `*/*/*` if you want depth 3 – Ben Usman Feb 13 '17 at 17:25
  • 2
    So basically, your suggestion only works as intended when all the files are exactly n levels deep, and there are no subfolders at that level. You should explain that. The latter might be surmountable by another flag for `ls`, and you can perhaps cover all levels up to `n` with `ls ... * */* */*/* ...` – mwfearnley Feb 14 '17 at 09:26
  • 1
    May not work: `bash: /bin/ls: Argument list too long` – Luc Jan 13 '20 at 10:35