How to recursively find the latest modified file in a directory?
Solution 1:
find . -type f -printf '%T@ %p\n' \
| sort -n | tail -1 | cut -f2- -d" "
For a huge tree, it might be hard for sort
to keep everything in memory.
%T@
gives you the modification time like a unix timestamp, sort -n
sorts numerically, tail -1
takes the last line (highest timestamp), cut -f2 -d" "
cuts away the first field (the timestamp) from the output.
Edit: Just as -printf
is probably GNU-only, ajreals usage of stat -c
is too. Although it is possible to do the same on BSD, the options for formatting is different (-f "%m %N"
it would seem)
And I missed the part of plural; if you want more then the latest file, just bump up the tail argument.
Solution 2:
Following up on @plundra's answer, here's the BSD and OS X version:
find . -type f -print0 \
| xargs -0 stat -f "%m %N" \
| sort -rn | head -1 | cut -f2- -d" "
Solution 3:
Instead of sorting the results and keeping only the last modified ones, you could use awk to print only the one with greatest modification time (in unix time):
find . -type f -printf "%T@\0%p\0" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\0'
This should be a faster way to solve your problem if the number of files is big enough.
I have used the NUL character (i.e. '\0') because, theoretically, a filename may contain any character (including space and newline) but that.
If you don't have such pathological filenames in your system you can use the newline character as well:
find . -type f -printf "%T@\n%p\n" | awk '
{
if ($0>max) {
max=$0;
getline mostrecent
} else
getline
}
END{print mostrecent}' RS='\n'
In addition, this works in mawk too.