Using GNU versions of find
, sort
, and head
(to make use of the NUL character to separate the filenames - NUL is the only character which is not valid in a path/filename, so it is the only character which can safely be used as a filename separator):
find . -maxdepth 1 -type f -name 'my_file_210804*' -print0 | sort -z -r | head -z -n 1
This will work with any filenames, no matter what characters they contain (including spaces, newlines, etc).
If you are absolutely certain that the filenames don't and won't ever contain newline characters, you can use newlines as the separator - drop the -print0
from the find
command, and the -z
option from sort
and head
.
find . -maxdepth 1 -type f -name 'my_file_210804*' | sort -r | head -n 1
This variant is also useful if the filenames are in a plain text file, with one filename per line:
sort -r filename-list.txt | head -n 1
If you want to sort the filenames by the timestamps in the filesystem (rather than by dates & times embedded in the filenames), it's a little more complicated. You need to use -printf
with a format string that includes the modification timestamp in seconds since the epoch (%T@
), a tab (\t
), the filename (%p
) and a NUL (\0
), rather than just -print0
:
find . -maxdepth 1 -type f -name 'my_file_210804*' -printf '%T@\t%p\0' |
sort -z -r -n -k 1,1 |
cut -z -f2- |
head -z -n 1
Here, sort ... -k1,1
is used to sort the output of find
by the first field (the timestamp), then cut
is used to remove the timestamp field and the tab character which separates it from the filename.
BTW, you may be tempted to parse the output of ls
. Don't do that, it doesn't work.
ls -1 *210804* | tail -1
? – doneal24 Jan 26 '22 at 02:29