Batch read file name and change content creation date

I have a lot of photos/videos named: 2012-04-05 19.21.34.jpg

Somehow, the creation date has been completely changed however.

Is there a way to replace the creation date with the info from the filename?


Solution 1:

If the naming convention is the same for all files in the same directory, then in Terminal, cd to that directory and use the following compound command:

for f in *.*; do touch -t $(sed -e 's:\.[a-z].*::' -e 's:\.::' -e 's:[- ]::g'<<<"$f") "$f"; done

Explanation of some of the compound command:

  • for f in *.*; do ...; done - Loop through files.
  • touch -t [[CC]YY]MMDDhhmm[.SS] - Change the access and modification times to the specified time instead of the current time of day.
  • $(...) - Command substitution, replaces the command(s) with the result, literally.
  • sed - Stream editor for filtering and transforming text.
    • −e script - Add the script to the commands to be executed.
    • 's:\.[a-z].*::' - This strips the file extension in e.g.: 2012-04-05 19.21.34.jpg
      • Returns: 2012-04-05 19.21.34
    • 's:\.::' - This removes the first . in e.g.: 2012-04-05 19.21.34
      • Returns: 2012-04-05 1921.34
    • 's:[- ]::g' - This removes - and the space in e.g.: 2012-04-05 1921.34
      • Returns: 201204051921.34

Which is the perfect format for the -t option in the touch command.


Please note that the original compound command is formed a bit loose. In other words, it can be written to expressly target .jpg files where the extension is lower case as in your example, e.g.: 2012-04-05 19.21.34.jpg

  • Replacing the *.* in for f in *.*; do ...; done with: in *.jpg
  • Replacing the [a-z].* in sed -e 's:\.[a-z].*::' with: jpg
for f in *.jpg; do touch -t $(sed -e 's:\.jpg::' -e 's:\.::' -e 's:[- ]::g'<<<"$f") "$f"; done

Since the -t option is being used with the touch command, any filename that doesn't produce the expected output, the worst case scenario with it written a bit loose is its not going to impact non-target files and will simply error out on those files with:

touch: out of range or illegal time specification: [[CC]YY]MMDDhhmm[.SS]

So, written a bit loose or more targeted, the end results will be the same and, only files with the naming convention of e.g. 2012-04-05 19.21.34.jpg will be touched.


NOTE: Always make sure you have a current backup before wholesale processing files.