Home » Linux » Rename JPG files according to date created

Rename JPG files according to date created

Posted by: admin November 30, 2017 Leave a comment


I want to rename all files in a certain directory. Renaming them to their date of creation.
So if my file is Image1.jpg, it should rename into something like “Jan 16 12:09:42 2011.jpg”
I want to do this through command line. I’ve been trying:

stat -f %SB Image0100.jpg

But how can I combine this with mv command? And how will I iterate stat and mv through the whole files?
Or are there simple ways to rename all files with their date creation?

jhead -n DSCN0382.JPG
DSCN0382.JPG --> 0408-150734.jpg

any strftime argument can be given as well:

jhead -n%Y%m%d-%H%M%S *.jpg 

This will rename files matched by *.jpg in the format YYYYMMDD-HHMMSS

jhead -n%Y%m%d-%H%M%S DSCN0382.JPG
DSCN0382.JPG --> 20120408-150734.jpg

see also the man page for lots of other cool options. You can for instance correct (shift) the EXIF date. This is very handy when merging files from different camera’s when some camera’s have an incorrect time set.


If you’re working with JPG that contains EXIF data (ie. from digital camera), then you can use following to get the creation date instead of stat.

exif -t 0x9003 -m Image0100.jpg

Updated: Per request, here’s the command and output. a couple of points to note:

  • Since not every file has exif data, we want to check that dst is valid before doing the rest of commands.
  • The output from exif has a space, which is a PITA for filenames. Use sed to replace with ‘-‘.
  • Note that I use ‘echo’ before the mv to test out my scripts. When you’re confident that it’s doing the right thing, then you can remove the ‘echo’… you don’t want to end up like the guy that got all the files blown away.

for i in *.jpg; do dst=$(exif -t 0x9003 -m $i ) && dst_esc=$(echo $dst | sed 's/ /-/g' ) && echo mv $i $dst_esc.jpg ; done

'12379632.jpg' does not contain tag 'DateTimeOriginal'.
mv 15084688.jpg 2003:02:28-21:48:54.jpg
mv 15136312.jpg 2003:03:01-10:36:05.jpg
mv 15137960.jpg 2003:03:01-10:36:38.jpg
mv 15140744.jpg 2003:03:01-10:37:46.jpg
for file in *jpg
 newfile=$(date "+%b %d %H:%M:%S%Y $file" -d "$(stat -c "%y" $file)")
 mv "$file" "$newfile"


Most POSIX filesystems do not record creation time (and the API certainly doesn’t expose it even if it is recorded), so you’re SOL.

$ for i in *; do mv "$i" "`stat -f %SB $i`"; done

find . -type f | xargs stat -f "mv %%N \"%%SB.jpg\"" | awk -F \; '{system $1;}'


If you, like me, have to google this over and over again because you’re getting older and can’t remember things, you can also use gThumb which has a batch renamer included which works well and has a old name -> new name preview. Real nice.


On MacOS X 10.6.6 with Bash (and, I think, with Korn shell), this works on file names with spaces in them:

echo > "x y"
for file in *
    x=$(stat -f '%SB' -t '%Y%m%d.%H%M%S' "$file")
    mv "$file" "$x"

It also uses the notation derived from ISO 8601 for the date and time. Clearly, if two files have the same modification time, the last of those file in alphabetic order is the only one that will survice. This also loses any suffix. If you’re dealing with ‘.jpg’ files, you’d probably want to use:

echo > "x y,jpg"
for file in *.jpg
    x=$(stat -f '%SB' -t '%Y%m%d.%H%M%S.jpg' "$file")
    mv "$file" "$x"

Since the output name ($x) has no spaces in it, there’s no need for the quotes around “$x” in the move command, but their presence is consistent.


Just use exiftool. Here’s an example from its documentation:

   exiftool -r '-FileName<CreateDate' -d %Y-%m-%d/%H%M_%%f.%%e dir
        Both the directory and the filename may be changed together via the
        "FileName" tag if the new "FileName" contains a '/'.  The example above
        recursively renames all images in a directory by adding a "CreateDate"
        timestamp to the start of the filename, then moves them into new
        directories named by date.


There is also:

rename -v 's/.JPG/.jpeg/' *.JPG
rename -v 's/.jpeg/.jpg/' *.jpeg
exiv2 -r'RP_%Y%m%d_%H%M%S' rename *.jpg

to give RP_20120801_063021.jpg for example. This works for Debian Linuxes (e.g. Ubuntu).

The rename commands are for when some images are .JPG or .jpeg. Cannot convert .JPG directly to .jpg as its interpreted as being the same…


A perl alternative:

I really like the short pattern to add a fixed-string prefix with perl:

/bin/ls *.jpg | perl -pe 's/.*/mv "$&" "prefix_$&"/' | sh

To make a date prefix, it is a bit more complicated.

cat >t.pl

while(<*.jpg>) {
    $mtime = (stat($_))[9];
    ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($mtime);
    $year += 1900;
    ++ $mon;
    printf("mv \"%s\" \"%d-%.2d-%.2d-%s\"\n", $_, $year, $mon, $mday, $_)

perl t.pl | sh