Set Modified Time to Date and Time Picture was Taken (in Linux)

Oh no! I just moved 3 gigs of pictures, afterwards realizing that the modified-time was changed from the time the picture was taken to the time the file was moved. What a mess, I thought, since I always refer to the modified-time when I wonder when a picture was taken.

exiv2 and touch to the rescue!

exiv2 will tell you, among a ton of other things, the time the picture was taken, and touch will allow you to change the modified-time of the image.

Note:Any command below, spread across multiple lines, is done so for clarity. To use the command, the line breaks must be removed such that the entire command is on one line!

This is the output of exiv2:

File name       : my_picture.jpg
File size       : 77443 Bytes
MIME type       : image/jpeg
Image size      : 425 x 543
Camera make     : Canon
Camera model    : Canon PowerShot SD1100 IS
Image timestamp : 2010:04:26 20:06:07
Image number    : 100-2025
Exposure time   : 1/60 s
Aperture        : F4.9
Exposure bias   : 0
Flash           : Yes, auto, red-eye reduction
Flash bias      : 0 EV
Focal length    : 18.6 mm
Subject distance: 266
ISO speed       : 250
Exposure mode   : Easy shooting (Auto)
Metering mode   : Multi-segment
Macro mode      : Off
Image quality   : Fine
Exif Resolution : 1848 x 2360
White balance   : Auto
Thumbnail       : JPEG, 7866 Bytes
Copyright       :
Exif comment    :

Now you just use grep to find the Image timestamp line:

exiv2 my_image.jpg | grep timestamp
Image timestamp : 2010:04:26 20:06:07

Now use awk to massage that date into almost the touch-required format of YYYYMMDDHHMM.SS

exiv2 my_image.jpg |
  grep timestamp |
    awk '{split($5,t,":");print $4,t[1],t[2],".",t[3]}'
2010:04:26 20 06 . 07

Now use sed to remove the space and colons to complete the formatting

exiv2 my_image.jpg |
  grep timestamp |
    awk '{split($5,t,":");print $4,t[1],t[2],".",t[3]}'  |
      sed 's/[:, ]//g'
201004262006.07

And the final command, to actually touch an image:

touch my_image.jpg -t
  `exiv2 my_image.jpg |
    grep timestamp |
      awk '{split($5,t,":");print $4,t[1],t[2],".",t[3]}' |
        sed 's/[:, ]//g'`

For an entire directory:

find *.jpg |
  while read f; do
    touch "${f}" -t `
      exiv2 "${f}" |
        grep timestamp |
          awk '{split($5,t,":");print $4,t[1],t[2],".",t[3]}' |
            sed 's/[:, ]//g'`;
  done

Leave a Reply