0

I'm looking for a good portable way of finding the oldest file in a directory tree matching a pattern, explicitly without using find's -printf option. So far I found this solution: https://superuser.com/a/552609/1182477 which I extend with a pattern like this:

find . -type f -name "*.csv" -print0 | xargs -0 ls -ltr | head -n 1

But this fails silently when no file matches the pattern. I get the oldest file regardless of the pattern. My diagnosis so far: when nothing matches the pattern, nothing gets passend into xargs and thus ls -ltr lists all files. How can I solve this? I want to get nothing out, when nothing matches the pattern.

And maybe, as a bonus, a solution that also avoids the ARG_MAX problem with long file lists? (And before someone asks: logrotate is not available on the system.)

One thing that I stumpled upon in my diagnostics and what could help me find a solution to the above:

ls *.csv

lists files matching that pattern. But

*.csv | xargs ls

lists all files. Shouldn't both of them do the same?

Thank You very much.

4
  • Define "portable". POSIX? Also runs in Windows?
    – xenoid
    May 31, 2020 at 12:19
  • The command xargs has an option -r which prevents the command from running if there list of arguments is empty.
    – Kapil
    May 31, 2020 at 13:12
  • @xenoid: look at the tags, so no windows. I'm not so sure which platforms I should aim at. All I know, I'm running busybox, and there's no -printf option in find.
    – PeterK
    May 31, 2020 at 14:51
  • @Kapil: Thank You for leaving the reputation of a good answer to me. ;-)
    – PeterK
    May 31, 2020 at 14:56

2 Answers 2

1

With busybox, your question can be answered by simply doing:

find . -type f -name "*.csv" -exec stat -c '%y %n'  {} + | sort | head -1

(removing the time stamp from the final result is left as an exercise for the reader)

This also avoids the SIGPIPE error you can get with your xargs-based version if there are very many files (unless you use this trick)

1
  • I have no stat on this BusyBox v1.30.1. (It's a router running it.) Answer works on my Ubuntu 20.04. Thanks for pointing to the tail -n +1 trick. But it doesn't relieve the signal 13 problem on neither systems.
    – PeterK
    Jun 1, 2020 at 20:03
0

So, thanks to the comment of Kapil I found this working:

find . -type f -name "*.csv" -print0 | xargs -0r ls -ltr | head -n 1

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .