How to Bulk-Add File Creation Date to Filename

batch-renamecommand linerename

I have generated a time-lapse series of images and have named them sequentially {0000..9999}.jpg

This isn't great for browsing the whole set as it's harder to tell when a given image was taken from its filename. I would like to rename them so their names contain their creation date, eg:

0000.jpg → 20140815-142800-0000.jpg
0001.jpg → 20140815-142800-0001.jpg
0002.jpg → 20140815-142800-0002.jpg

It's important to preserve the original filename elements and the exact date formatting isn't that important, as long as it's filename-safe and easy to understand. My example above inserts it at the front in a way that is conducive to sorting by date.

If you want test harness of files, the following will create 10 files with ascending creation times:

for i in {00..02}; do touch --date "2014-08-15 $i:$i:$i" 00$i.jpg; done

Best Answer

You can use rename with a real Perl expression

$ rename 's/(\d+\.jpg)/use File::stat; sprintf("%s-%s", stat($&)->mtime, $1)/e' * -v
0000.jpg renamed as 1408057200-0000.jpg
0001.jpg renamed as 1408060861-0001.jpg
0002.jpg renamed as 1408064522-0002.jpg

That leaves the files with a time-since-epoch. Find for sorting, poor for reading.

The only problem here is you need to match the whole filename (so that you can stat $& —aka the entire match— inside the substitution). That could get a little tiresome with really complicated names.

We can build on that to have a more conventional date formatting:

$ rename 's/(\d+\.jpg)/use File::stat; use POSIX; sprintf("%s-%s", strftime("%Y%m%d-%H%M%S", localtime(stat($&)->mtime)), $1)/e' * -vn
0000.jpg renamed as 20140815-000000-0000.jpg
0001.jpg renamed as 20140815-010101-0001.jpg
0002.jpg renamed as 20140815-020202-0002.jpg
Related Question