Reputation: 777
Given the path of a directory, how can I return the path of the newest file in that directory?
Upvotes: 7
Views: 1025
Reputation: 495
via xuchunyang, except his version sorts in reverse lexicographic order instead of modification time. This one is slower but does get most recently modified file:
(defun latest-file (path &optional match)
(car (sort (directory-files path 'full match t) #'file-newer-than-file-p)))
;; most recently modified file in ~/.emacs.d (non-recursive)
(latest-file "~/.emacs.d")
;; most recently modified file in ~/.emacs.d with .el extension
(latest-file "~/.emacs.d" ".*\\.el$")
Upvotes: 0
Reputation: 11
If you want to do it without dependencies
directory-files-and-attributes
gives us a list of files and directories with attributes
NOSORT
is a bool and does not take a function as the top answer suggests(directory-files-and-attributes DIRECTORY &optional FULL MATCH NOSORT ID-FORMAT)
If NOSORT is non-nil, the list is not sorted--its order is unpredictable. NOSORT is useful if you plan to sort the result yourself.
file-attributes
- which gives us the modification time and whether the item is a file or directory
- t for directory, string (name linked to) for symbolic link, or nil.\
- Last modification time, likewise. This is the time of the last
(car
(seq-find
'(lambda (x) (not (nth 1 x))) ; non-directory
(sort
(directory-files-and-attributes path 'full nil t)
'(lambda (x y) (time-less-p (nth 5 y) (nth 5 x)))))) ; last modified first: y < x
Upvotes: 1
Reputation: 959
Using built-in APIs can achieve as well:
(defun latest-file (path)
"Get latest file (including directory) in PATH."
(car (directory-files path 'full nil #'file-newer-than-file-p)))
(latest-file "~/.emacs.d") ;; => "/Users/xcy/.emacs.d/var"
If you also needs files under sub-directory, use directory-files-recursively
rather than directory-files
. If you want to exclude directories, filter the file/directory list first by using file-directory-p
.
Upvotes: 7