6

How do I find out the most recently accessed file in a given directory?

I can use the find command to list out all files modified/accessed in last n minutes. But here in my case, I'm not sure when the last file was modified/accessed? All that I need is to list all the files which were accessed/modified very recently among all other sub-files or sub-directories, sorted by their access/modified times, for example.

Is that possible?

  • Your question is unclear. Are you saying you want to take the list of files from find and sort them by date? – RobertL Nov 3 '15 at 7:19
  • 2
    Oh, I see. I think. You want to sort the full set of "recent" files by their access/modify time, regardless of their location in the file tree? – roaima Nov 3 '15 at 14:39
2

You could use the recursive switch (-R) to ls along with the sort by time switch (-t) and the reverse sort switch (-r) to list out all the files in a directory tree. This will not sort all the files by their access/modify dates across sub-directories, but will sort them by this date within each sub-directory independently.

Using a command such as this: ls -ltrR <sometopdir>.

Example

$ ls -ltrR .
total 759720
-rw-r-----@  1 sammingolelli  staff    2514441 Mar 31  2015 restfulapi-120704053212-phpapp01.pdf
-rw-r-----@  1 sammingolelli  staff     567808 Apr  7  2015 USGCB-Windows-Settings.xls
-rw-r-----@  1 sammingolelli  staff     180736 Apr  7  2015 USGCB-RHEL5-Desktop-Settings-Version-1.2.5.0.xls
-rw-r-----@  1 sammingolelli  staff       6474 Apr  8  2015 tap_kp_mavericks.txt

./kerberos:
total 5464
-rw-r-----@ 1 sammingolelli  staff    37317 Oct  2 13:03 Set_up_Kerberos_instruction_d8.docx
-rw-r-----@ 1 sammingolelli  staff  2753195 Oct 13 13:49 Keberos configuration with AD 01_09_2014.pdf

./homestarrunner:
total 10624
-rw-rw-rw-@ 1 sammingolelli  staff   319422 May 10  2000 error_hs.wav
-rw-rw-rw-@ 1 sammingolelli  staff    53499 Jun  8  2001 sb_duck.mp3
-rw-rw-rw-@ 1 sammingolelli  staff   199254 Mar 11  2002 email_sb.wav
-rw-rw-rw-@ 1 sammingolelli  staff    39288 Mar 25  2002 bubs_dontutalk.mp3
-rw-rw-rw-@ 1 sammingolelli  staff    75432 May  6  2002 trash_sb.wav
-rw-rw-rw-@ 1 sammingolelli  staff   298946 Dec  1  2002 error_sb.wav
-rw-rw-rw-@ 1 sammingolelli  staff   298686 Dec  1  2002 startup_hs.wav
-rw-rw-rw-@ 1 sammingolelli  staff    90279 Dec  1  2002 sb_meedlymee.mp3
-rw-rw-rw-@ 1 sammingolelli  staff    73561 Dec  1  2002 sb_dubdeuce.mp3
-rw-rw-rw-@ 1 sammingolelli  staff   193097 Dec  1  2002 sb_pizza.mp3
-rw-rw-rw-@ 1 sammingolelli  staff    30093 Dec  1  2002 sb_stiny.mp3
-rw-rw-rw-@ 1 sammingolelli  staff    61858 Dec  1  2002 ss_sadflying.mp3
-rw-rw-rw-@ 1 sammingolelli  staff   150142 Dec  1  2002 email_hs.wav
-rw-rw-rw-@ 1 sammingolelli  staff    68545 Dec  1  2002 bubs_grabbinbutt.mp3
-rw-rw-rw-@ 1 sammingolelli  staff    61022 Dec  1  2002 cz_jeorghb.mp3
-rw-rw-rw-@ 1 sammingolelli  staff    40124 Dec  1  2002 marzy_nasty.mp3
-rw-rw-rw-@ 1 sammingolelli  staff   224116 Dec  1  2002 shutdown_sb.wav
-rw-rw-rw-@ 1 sammingolelli  staff   260546 Dec  1  2002 shutdown_hs.wav
-rw-rw-rw-@ 1 sammingolelli  staff    57686 Dec  1  2002 trash_hs.wav
4

To print the last 3 accessed files (sorted from the last accessed file to the third last accessed file):

find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print $2}'

To print the last 3 modified files (sorted from the last modified file to the third last modified file):

find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print $2}'
  • find . -type f -exec stat -c '%X %n' *: prints the last access' time followed by the file's path for each file in the current directory hierarchy;
  • find . -type f -exec stat -c '%Y %n' *: prints the last modification's time followed by the file's path for each file in the current directory hierarchy;
  • sort -nr: sorts in an inverse numerical order;
  • awk 'NR==1,NR==3 {print $2}': prints the second field of the first, second and third line.

You can change the number of files to be shown by changing 3 to the desired number of files in awk 'NR==1,NR==3 {print $2}'.

% touch file1
% touch file2
% touch file3
% find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print }'
./file3
./file2
./file1
% find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print }'
./file3
./file2
./file1
% cat file1
% find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print }'
./file1
./file3
./file2
% find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print }'
./file3
./file2
./file1
% touch file2
% find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print }'
./file2
./file1
./file3
% find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk 'NR==1,NR==3 {print }'
./file2
./file3
./file1
  • Command is not honouring the year – SHW Nov 3 '15 at 8:22
  • @SHW Not sure what you mean. The files are sorted based on the number of seconds passed from January 1st 1970. – kos Nov 3 '15 at 8:28
  • Works on Mac OS X but with a slight tweak to the stat command: stat -f '%Dm %N' – Matt Kneiser Jan 10 at 18:47
2

If you want the files in a given directory sorted by modification age (most recent first):

ls -t

To sort by access time, add the -u option.

ls -tu

However, beware that modern Linux systems do not track exact access times by default. So the access timestamps may not be reliable.

If you want to find the most recent file within a directory tree, including subdirectories, the easiest method by far is to use zsh's glob qualifiers.

print -lr -- **/*(om)

Use oa instead of om to use the access time rather than the modification time. You can restrict the matches, for example to get the 10 most recent files:

print -lr -- **/*(om[1,10])
1

You want to sort the full set of "recent" files by their access/modify time, regardless of their location in the file tree?

One way of doing this is to use stat to print the modify time for each file, sort by the result, and then cut the modification time from the results.

This will break for files containing newlines in their names, but for other files here's a solution that will list files modified within the last 60 minutes, ordered from most recently to least recently modified:

find . -type f -mmin -60 -exec stat -c $'%Y\t%n' {} + | sort -nr | cut -f2-
0

Let's put this into a cross-platform bash function:

# Print N most recently modified files in current dir or below
mrf() {
    local _n=${1:-3} # Default to 3
    case $OSTYPE in
        linux*|msys*)
            find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk -v var="${_n}" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done
        ;;
        darwin*)
            find . -type f -exec stat -f '%Dm %N' {} \; | sort -nr | awk -v var="${_n}" 'NR==1,NR==var {print $2}' | while read f; do stat -f '%Sm -- %N' $f; done
        ;;
     esac
 }

Usage:

$ mrf
Jan 10 11:50:03 2019 -- ./somefile
Jan 10 11:44:24 2019 -- ./nested/dir/file.txt
Jan 10 11:40:50 2019 -- ./anotherfile

$ mrf 5
Jan 10 11:50:03 2019 -- ./somefile
Jan 10 11:44:24 2019 -- ./nested/dir/file.txt
Jan 10 11:40:50 2019 -- ./anotherfile
Jan 10 06:30:22 2019 -- ./otherdir/yetanotherfile
Jan 09 10:00:00 2019 -- ./oldfile
0

This command also provide the most recently modified file or directory from the current directory tree:

% find . -printf '%TY-%Tm-%TdT%TT %p\n' |sort |tail -1
2019-01-30T17:29:18.0330479800 ./servlet-api/META-INF/NOTICE

Of course, you can change the last argument to the number of most recent files you might need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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