I hope all is good for you.

I have some files like that:


I want to retrieve the last version of the file by a unix command.

For example for the file 210804 I want to retrieve only my_file_210804_2056_856.csv_20211119181137 because it's the last.

Thanks for your help

  • Assuming no newline or other special characters in the file name, perhaps ls -1 *210804* | tail -1?
    – doneal24
    Jan 26, 2022 at 2:29

1 Answer 1


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.

  • "/" is forbidden in filenames, too.
    – waltinator
    Jan 26, 2022 at 2:38
  • NOTE: find will output filenames with the path (relative to the "starting point" directory). You can remove the paths with sed, or bash's built-in parameter expansion features (e.g. ${parameter#word} or ` ${parameter/pattern/string}), or with basename`
    – cas
    Jan 26, 2022 at 2:40
  • @waltinator that's why I said "path/filename". find returns pathnames.
    – cas
    Jan 26, 2022 at 2:41

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.