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
up vote 1 down vote accepted

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; 
    do
        created=$(stat -f "%m" $file)
        dateHat=$(date -r $created "+%F" )
        sizeBytes=$(stat -f "%z" $file)
        mv $file $dateHat"_size_"$sizeBytes"_"$file
    done

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.