Rename and redate photo-files

Summary

HJG 2006-06-25 - Digital cameras typically produce pictures, voice-memos and movies with filenames like "100_0001.jpg", "Dscn0001.wav", "Imgp0001.jpg" and "Dscn1234.mov".

For organizing a collection of photos, it is better to rename them to a filename based on a prefix and the date and time of when the picture was taken, such as "holidays_2005-12-13_14-15-16.jpg" or "gurt2005_1213_141516a.jpg". (I prefer to use as few separators as possible)

Some software that can do such renaming:

Of course, we can do that with Tcl/Tk too.

Program 1

Here is a simple program for renaming just the jpg-files:


  # FotoRename1.tcl - HaJo Gurt - 2006-06-25 - https://wiki.tcl-lang.org/16082
  #: Rename jpg-files in current directory,
  # according to date and time, as specified in fnFormat,
  #: e.g. "dscn1234.jpg" --> "gurt2006_0625_121314.jpg"

  catch {console show}                ;# works in wish as well as tclsh
  catch {wm withdraw .}

  set dir "."
  set fnFormat "gurt%Y_%m%d_%H%M%S"

  puts "# FotoRename1:"
  foreach fname1 [lsort [glob -dir $dir "*.jpg"]] {
    file stat $fname1 stat
    array set attr [file attributes $fname1]
    set fn1 [file tail $fname1]

    if { $stat(type) == "file" } {
      set fn2 [clock format $stat(mtime) -format $fnFormat ]
      set ext ".jpg"
      append fn2 $ext
      if { [file exist $fn2] } {
        puts "# $fn1 - File exists: $fn2"                ;# don't overwrite existing files
      } else {
        puts [format "mv %-30s %s" $fn1 $fn2]
        file rename -- $fn1 $fn2                
      }
    }
  }
  puts "# Done."

Comments 1

This assumes that the modification-date of the image-files is the date and time when the picture was shot, and that we have sufficent permissions for the renaming.

This program does not consider files with the same date+time (other than not renaming more than one of them), i.e. photos that were shot within the same second.

The script simply works on files in its directoy, so to use it, move or copy the script to the directoy containing the files, then run it.

Program 2

The next version of the program renames the jpg-files (fotos) as well as mov-files (movies):


  # FotoRename2.tcl - HaJo Gurt - 2010-11-22
  #: Rename camera-files (jpg, mov) in current directory,
  # according to date and time, as specified in fnFormat
  #: e.g. "dscn2345.jpg" --> "gurt2010_1122_131415.jpg"

  catch {console show}                ;# works in wish as well as tclsh
  catch {wm withdraw .}

  set dir "."
  set fnFormat "gurt%Y_%m%d_%H%M%S"
  set files 0
  set ok    0

  puts "# FotoRename2:"
  # Filenames: dscn####  sscn####
  foreach fname1 [lsort [glob -nocomplain -dir $dir -types f "?sc*.{jpg,mov}"]] {
    incr files
    file stat $fname1 stat
    array set attr [file attributes $fname1]
    set fn1 [file tail      $fname1]
    set ex1 [file extension $fname1]

    set fn2 [clock format $stat(mtime) -format $fnFormat ]
    append fn2 $ex1

    if { [file exist $fn2] } {
      puts "# $fn1 - File exists: $fn2"                ;# don't overwrite existing files
    } else {
      puts [format "mv %-30s %s" $fn1 $fn2]
      file rename -- $fn1 $fn2
      incr ok
    }

  }
  puts "# Files: $files  Renamed: $ok"

Comments 2

Now, it would be nice to also rename voice-memos-files. On my camera, for each picture a voice-memo can be recorded. This gets the same basename as the picture (e.g. dscn3333.jpg and dscn3333.wav), but the voicefile gets the timestamp from the time of the recording. So, after a 'simple' renaming, the connection between picture and memo would be lost.

Another desirable function would be re-dating photo-files according to the date+time from their exif-info, and optionally correcting this date by some offset (e.g. when you forgot to set the camera for daylight-saving-time, or on holidays in another timezone).


See also: