sort directories by last modified content (recursive)

The last modification time of a directory (think like phone directory, not folder) is the time it was last modified, like when an entry was removed, added or edited in that directory.

To find out the newest regular file recursively in it, you would need to read the contents of that directory and every directory within and for each file, check the file's modification time. That's a costly thing to do, I wouldn't expect any file manager application to do it.

You could however script it.

With the GNU implementations of find and sort (and any Bourne-like shell), you could do:

TZ=UTC0 find . -mindepth 2 -type f -printf '%TFZ%TT/%P\0' |
  LC_ALL=C sort -zt/ -k2,2 -k1,1r |
  LC_ALL=C sort -t/ -zmsuk2,2 |
  LC_ALL=C sort -z |
  tr '\0' '\n'

Which would give something like:

2020-02-08Z19:17:22.3588966190/Scripts/.distfiles
2020-02-09Z09:25:37.5336986350/StartupFiles/zshrc
2020-07-26Z20:33:17.7263164070/Misc/vcs_info-examples
2020-07-26Z20:33:17.7463157170/Util/ztst-syntax.vim
2020-08-22Z18:06:17.9773156630/Functions/VCS_Info
2020-08-30Z11:11:00.5701005930/autom4te.cache/requests
2020-08-30Z11:11:31.5245491550/Config/defs.mk
2020-08-30Z11:11:31.6085449480/Etc/Makefile
2020-08-30Z11:12:10.9305773600/INSTALL.d/share/zsh/5.8.0.2-dev/help
2020-10-22Z05:17:15.3808945480/Completion/Base/Utility
2020-10-22Z05:17:15.3928938520/Doc/Zsh/zle.yo
2020-10-22Z05:17:15.3968936190/Src/zsh.h
2020-10-22Z05:17:15.3968936190/Test/D02glob.ztst
2020-10-22Z05:17:15.4168924590/.git/logs/refs/heads/master

That is, giving the newest regular file in each directory with its timestamp. Directories without regular files in them are not shown.

To only see the list of directories, insert a cut -zd/ -f2 | before the tr command.

For a prettier output like in the zsh approach, you could replace the tr command with:

LC_ALL=C gawk -v RS='\0' -F / '{
  dir = $2; mtime = $1
  sub("[^/]*/[^/]*/", "")
  printf "%-20s %s (%s)\n", dir, mtime, $0}'

While we're at using gawk, we could also tell find to print the timestamp as a fractional Unix epoch time and gawk reformat it in local time:

find . -mindepth 2 -type f -printf '%T@/%P\0' |
  LC_ALL=C sort -zt/ -k2,2 -k1,1rn |
  LC_ALL=C sort -t/ -zmsuk2,2 |
  LC_ALL=C sort -zn |
  LC_ALL=C gawk -v RS='\0' -F / '{
    dir = $2; split($1, mtime, ".")
    sub("[^/]*/", "")
    printf "%-20s %s (%s)\n", dir, strftime("%FT%T." mtime[2] "%z", mtime[1]), $0}'

Which would give an output like:

cross-build          2019-12-02T13:48:33.0505299150+0000 (cross-build/x86-beos.cache)
m4                   2019-12-02T13:48:33.4615093990+0000 (m4/xsize.m4)
autom4te.cache       2019-12-02T13:50:48.8897482560+0000 (autom4te.cache/requests)
CWRU                 2020-08-09T17:17:21.4712835520+0100 (CWRU/CWRU.chlog)
include              2020-08-09T17:17:21.5872807740+0100 (include/posixtime.h)
tests                2020-08-09T17:17:21.8392747400+0100 (tests/type.right)
.git                 2020-08-09T17:17:21.8472745490+0100 (.git/index)
doc                  2020-08-09T17:35:35.1638603570+0100 (doc/Makefile)
po                   2020-08-09T17:35:35.3758514290+0100 (po/Makefile)
support              2020-08-09T17:35:36.7037954930+0100 (support/man2html)
lib                  2020-08-09T17:35:42.3755564970+0100 (lib/readline/libhistory.a)
builtins             2020-08-09T17:35:42.5035511020+0100 (builtins/libbuiltins.a)
examples             2020-08-09T17:35:47.1513551370+0100 (examples/loadables/cut)
INSTALL.d            2020-08-09T17:35:47.3993446790+0100 (INSTALL.d/lib/bash/cut)

In zsh, you could define a by_age_of_newest_file sort order function like:

zmodload zsh/stat
typeset -A newest_mtime newest_file
by_age_of_newest_file() {
  local dir=${1-$REPLY}
  local newest=($dir/**/*(ND.om[1]))

  if (($#newest)); then
    stat -gLA REPLY -F %FZ%T.%N +mtime -- $newest
    newest_mtime[$dir]=$REPLY newest_file[$dir]=$newest
  else
    REPLY= newest_mtime[$dir]= newest_file[$dir]=
  fi
}

Which you could use as:

print -rC1 -- *(ND/o+by_age_of_newest_file)

to print the list from oldest to newest (dirs with no file listed first). Replace o+ with O+ to reverse the order.

Or to print the directories alongside the newest file and its timestamp:

data=()
for dir (*(ND/o+by_age_of_newest_file))
  data+=("$dir" "$newest_mtime[$dir]" "($newest_file[$dir])")
print -raC3 -- "$data[@]"

Which gives something like:

Scripts                        2020-02-08Z19:17:22.358896619  (Scripts/.distfiles)
StartupFiles                   2020-02-09Z09:25:37.533698635  (StartupFiles/zshrc)
Misc                           2020-07-26Z20:33:17.726316407  (Misc/vcs_info-examples)
Util                           2020-07-26Z20:33:17.746315717  (Util/ztst-syntax.vim)
Functions                      2020-08-22Z18:06:17.977315663  (Functions/VCS_Info/Backends/VCS_INFO_get_data_hg)
autom4te.cache                 2020-08-30Z11:11:00.570100593  (autom4te.cache/requests)
Config                         2020-08-30Z11:11:31.524549155  (Config/defs.mk)
Etc                            2020-08-30Z11:11:31.608544948  (Etc/Makefile)
INSTALL.d                      2020-08-30Z11:12:10.870580360  (INSTALL.d/share/zsh/5.8.0.2-dev/help/zstyle)
Completion                     2020-10-22Z05:17:15.380894548  (Completion/Base/Utility/_store_cache)
Doc                            2020-10-22Z05:17:15.392893852  (Doc/Zsh/zle.yo)
Src                            2020-10-22Z05:17:15.396893619  (Src/zsh.h)
Test                           2020-10-22Z05:17:15.396893619  (Test/D02glob.ztst)
.git                           2020-10-22Z05:17:15.416892459  (.git/logs/refs/heads/master)

(note the timestamps are in Zulu/UTC time)