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

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.