Sort the files in the directory recursively based on last modified date

I have modified a lot of files in my directory want to know what are those files by sorting them by the last modified date and in that I want some of the extensions to be excluded

in the svn directory I have a lot of .svn files too which I don't want to show in the sort

  • I demo how to exclude the extension in my answer.
    – mikeserv
    Apr 2, 2014 at 4:51

7 Answers 7

find -printf "%TY-%Tm-%Td %TT %p\n" | sort -n

will give you something like

2014-03-31 04:10:54.8596422640 ./foo
2014-04-01 01:02:11.9635521720 ./bar

  • Can i exclude an file extension from the folder....
    – Danny
    Apr 2, 2014 at 4:44
  • @Danny Yes, that's easy with find: find -not -iname '*.ext'.
    – n.st
    Apr 2, 2014 at 6:13
  • find -not -path "svn" -not -name "*svn" -printf "%TY-%Tm-%Td %TT %p\n" | sort -n this is exactly what I needed thanks a lot @ n.st
    – Danny
    Jun 9, 2014 at 7:21
  • 1
    I get find: illegal option -- p Feb 25, 2021 at 4:57
  • 1
    @nealmcb that's not correct. The option is -type f e.g. find -type f -printf "....
    – glarrain
    Aug 11, 2022 at 13:17

If you want to flatten the directory structure (thus sorting by date over all files in all directories, ignoring what directory the files are in) the find-approach suggested by @yeti is the way to go. If you want to preserve directory structure, you might try

$ ls -ltR /path/to/directory

which sorts directory based.

  • 1
    this give me folder wise where as what I need is all together what are the recently modified files
    – Danny
    Apr 2, 2014 at 4:45

In bash, run shopt -s globstar first. In ksh93, run set -o globstar first. In zsh, you're already set.

ls -dltr **/*

This will return an error if you have so many files that the command line length limit on your system is exceeded. In zsh, you can use this instead:

print -rl -- **/*(Om)

This one will list all files in <dir> with topmost being oldest modified

find <dir> -type f -print0 | xargs -0 ls -ltr

And with this the latest modified is topmost

find <dir> -type f -print0 | xargs -0 ls -lt

Note that this only works if the list of file names doesn't exceed the total command line length limit on your system.


Assuming you are usuig GNU find, try:

find $SOMEPATH -exec stat -c '%Y %n' '{}' + | sort -n
  • 1
    You could use find's -printf option to avoid invoking a separate process (or several, depending on the number of files). See my answer for an example.
    – n.st
    Apr 1, 2014 at 23:53
  • 1
    Knowing that there are other ways to do it, I wanted to give stat a chance and show -exec ... +. Really! Sometimes I think, stat deserves more attention... and noone should take recipes from here without reading about the ingredients and thinking about consequences...
    – user62916
    Apr 2, 2014 at 4:43
  • Btw... not every find has -printf...
    – user62916
    Apr 2, 2014 at 4:49
  • 1
    @yeti - If your find doesn't have -printf, you can use -exec sh -c 'printf...' to get much of the same functionality. That would include access to $(pwd) for fully qualified paths as well.
    – mikeserv
    Apr 2, 2014 at 6:00
  • 2
    I met lots of linux users never having read about stat. So sometimes I just want to direct some attention on stat... I think stat deserves it...
    – user62916
    Apr 2, 2014 at 6:06

To robustly list the filenames only using recent GNU tools:

find . -printf '%A@ %p\0' |
  sort -nz |
  sed -z 's/^[^ ]* //' |
  tr '\0' '\n'
find $DIR -depth -maxdepth 3 \
    -type d -readable -printf \
    'printf "\\n%p\\n"
    ls -t --color=always "%p"\n' |\
    . /dev/stdin 2>&-

This avoids any argument list problems because the only argument ls will ever receive is the name of the directory you want listed. You can do this with anything you like.

The shell just . sources the |pipe as a shell script - it's the same process and doesn't have the issues you can encounter when execve is called.

In any case - the above only goes three-deep which is adjustable by changing maxdepth. It also deep first - so you work your way backwards to your current directory from depth.

You might notice you also get $LSCOLORS - on my machine it also provides neatly printed columns and everything else you would want from ls - or, for that matter, anything you can imagine you'd wanna do with . source.


Again, this'll do anything you expect of ls. So hiding .svn files is as simple as changing the ls line to:

ls -t --color=always --hide="*svn" "%p"\n

Or if you want to see svn extensions in every folder BUT ./svn you could change it so the whole command looks like this:

    find $DIR -depth -maxdepth 3 \
        -type d -readable -printf \
            'printf "\\n%p\\n" ; hide=
            [ "%p" = "./svn" ] && hide="*svn"
            ls -t --color=always --hide="$hide" "%p"\n' |\
    . /dev/stdin 2>&-

Personally, I like it with ls's -s and, if you care, -u will sort by access time rather than mod time.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .