Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I get the list of all files under current directory along with their modification date and sorted by that date?

Now I know how to achieve that with find, stat and sort, but for some weird reason the stat is not installed on the box and it's unlikely that I can get it installed.

Any other option?

PS: gcc is not installed either

share|improve this question
    
Can you upload a compiled binary and run it there? –  imz -- Ivan Zakharyaschev Mar 14 '11 at 19:58
    
@imz: yes, that's another way to go. The find -printf action seems to be the easiest though. –  alex Mar 15 '11 at 10:09

4 Answers 4

up vote 10 down vote accepted

My shortest method uses zsh:

print -rl **/*(.Om)

If you have GNU find, make it print the file modification times and sort by that. I assume there are no newlines in file names.

find . -type f -printf '%T@ %p\n' | sort -k 1 -n | sed 's/^[^ ]* //'

If you have Perl (again, assuming no newlines in file names):

find . -type f -print |
perl -l -ne '
    $_{$_} = -M;  # store file age (mtime - now)
    END {
        $,="\n";
        print sort {$_{$b} <=> $_{$a}} keys %_;  # print by decreasing age
    }'

If you have Python (again, assuming no newlines in file names):

find . -type f -print |
python -c 'import os, sys; times = {}
for f in sys.stdin.readlines(): f = f[0:-1]; times[f] = os.stat(f).st_mtime
for f in sorted(times.iterkeys(), key=lambda f:times[f]): print f'

If you have SSH access to that server, mount the directory over sshfs on a better-equipped machine:

mkdir mnt
sshfs server:/path/to/directory mnt
zsh -c 'cd mnt && print -rl **/*(.Om)'
fusermount -u mnt

With only POSIX tools, it's a lot more complicated, because there's no good way to find the modification time of a file. The only standard way to retrieve a file's times is ls, and the output format is locale-dependent and hard to parse.

If you can write to the files, and you only care about regular files, and there are no newlines in file names, here's a horrible kludge: create hard links to all the files in a single directory, and sort them by modification time.

set -ef                       # disable globbing
IFS='
'                             # split $(foo) only at newlines
set -- $(find . -type f)      # set positional arguments to the file names
mkdir links.tmp
cd links.tmp
i=0 list=
for f; do                     # hard link the files to links.tmp/0, links.tmp/1, …
  ln "../$f" $i
  i=$(($i+1))
done
set +f
for f in $(ls -t [0-9]*); do  # for each file, in reverse mtime order:
  eval 'list="${'$i'}         # prepend the file name to $list
$list"'
done
printf %s "$list"             # print the output
rm -f [0-9]*                  # clean up
cd ..
rmdir links.tmp
share|improve this answer
    
The easiest way is probably find . -print | xargs -n99999 -s999999 ls -ltr. But that has the problem that (1) xargs may not allow -m greater than 512 or -s greater than 5120, and (b) even if you can get around that, there's still a kernel-imposed maximum size of the combined argument list and environment. Most of your ideas (save the Perl and Python ones) have the same problem, which is why I specifically avoided building long command lines. –  geekosaur Mar 14 '11 at 22:49
    
In particular, I regularly get "argument list too long" errors using zsh recursive globs in the general case. –  geekosaur Mar 14 '11 at 22:51
    
@geekosaur: Only the last horrible kludge has a problem with long command lines. In zsh, you can do a lot with built-ins (e.g. print -rl **/*'s only limit is how much free memory you have), and beyond that there's zargs. Your proposal of find … | xargs … ls will sort correctly if xargs ends up invoking ls only once, and won't work if there are special characters in file names. –  Gilles Mar 14 '11 at 23:00
    
many thanks for extremely detailed answer with lot of options! :) –  alex Mar 15 '11 at 6:35
    
And that’s why I love zsh. –  Profpatsch Nov 8 '13 at 20:35

Assuming GNU find:

find . -printf '%T@ %c %p\n' | sort -k 1n,1 -k 7 | cut -d' ' -f2-

Change 1n,1 to 1nr,1 if you want the files listed most recent first.

If you don't have GNU find it becomes more difficult because ls's timestamp format varies so much (recently modified files have a different style of timestamp, for example).

share|improve this answer
    
Actually you can also change the date and time format with ls --time-style="..." - I'm not sure whether this is standard or GNU ls, likely GNU. –  asoundmove Mar 14 '11 at 22:22
    
Definitely GNU. –  geekosaur Mar 14 '11 at 22:28
    
@asoundmove: unfortunately, the box is too old (RedHat 7.2) and ls doesn't have that option. –  alex Mar 15 '11 at 6:19

On a mac there is no -printf argument to find, but you can do this instead:

find . -print0 | xargs -0 -n 100 stat -f"%m %Sm %N" | sort -n|awk '{$1="";print}'

share|improve this answer

one can try this (one has to build it oneself though) https://github.com/shadkam/recentmost

share|improve this answer
3  
Welcome to Unix & Linux Stack Exchange! Whilst this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference. –  slm Mar 7 at 10:51
    
While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. –  Raphael Ahrens Mar 7 at 11:35

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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