Is there a cross-*nix compatible way to get file modified timestamp?

2

Trying to solve this problem I've come up with solutions that are not compatible between ubuntu and osx. I wish to make one replacement command for the following two, which differ in two characters:

osx:

find . -type f -exec stat -f "%m {}" {} \;| sort -n | tail -n 1 | cut -d ' ' -f 2

ubu:

find . -type f -exec stat -c "%Y {}" {} \;| sort -n | tail -n 1 | cut -d ' ' -f 2

audio.zoom

Posted 2012-05-22T18:19:06.223

Reputation: 1 413

Answers

2

The stat command is not part of POSIX, so systems are allowed to have differing implementations.

Assuming Perl is available, the following should work:

-exec perl -MFile::stat -e 'print stat($_)->mtime, " $_\n" for @ARGV' {} \;

-exec perl -e 'print ((stat($_))[9], " $_\n") for @ARGV' {} \;

The version with -MFile::stat is more readable, but unfortunately several times slower.

The complete script would look like:

find . -type f -exec perl -e 'print ((stat($_))[9], " $_\n") for @ARGV' {} + |
  sort -n | tail -n 1 | cut -d " " -f 2-

(note the 2- at the end)

user1686

Posted 2012-05-22T18:19:06.223

Reputation: 283 655

Had to change \t to a space to fit the example, but the rest works great on both systems. Thanks! – audio.zoom – 2012-05-22T19:22:33.523

@audio.zoom: I used \t intentionally since file names very often have spaces and your cut -d ' ' -f 2 would have discarded everything after the first space. – user1686 – 2012-05-22T20:56:03.077

@audio.zoom: Also, does OS X find support using -exec ... {} + instead of -exec ... {} \;? The + form would be several times faster. – user1686 – 2012-05-22T20:57:32.047

Yes osx, at least 10.6, supports -exec + ...and thanks for catching that space bug! – audio.zoom – 2012-05-23T09:24:11.640

grawity, I'm wondering if you could update your script for using the + notation because I'm not sure if the current script will handle spaces correctly with it anymore – audio.zoom – 2012-05-25T10:42:27.660

@audio.zoom: It's just a matter of replacing \; at the end with +. The space bug is unrelated; you have to tell cut to either use -d $'\t' as delimiter, or if you changed my code back to spaces, then -f 2- as fields. (I had completely forgotten about the 2- syntax...) – user1686 – 2012-05-25T10:43:18.747