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

3 Answers 3


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

And something bash-based for simple filenames (like the example):

$ for f in *; do mv "$f" "$(date -d@$(stat --printf='%Y' "$f") +%Y%m%d%H%M%S)-$f"; done
$ ls -l
total 0
-rw-rw-r-- 1 oli oli 0 Aug 15 00:00 20140815000000-0000.jpg
-rw-rw-r-- 1 oli oli 0 Aug 15 01:01 20140815010101-0001.jpg
-rw-rw-r-- 1 oli oli 0 Aug 15 02:02 20140815020202-0002.jpg

Here's something I reworked so I could actually understand what was going on. Thanks.

for file in *.log; 
        created=$(stat -f "%m" $file)
        dateHat=$(date -r $created "+%F" )
        sizeBytes=$(stat -f "%z" $file)
        mv $file $dateHat"_size_"$sizeBytes"_"$file

You must log in to answer this question.

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