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?

  • 2
    Are all photos named in the same form? Are they all in the same directory or spread across several? – nohillside Aug 26 at 20:54
  • 1
    All named in the same form, and in the same directory! – EinsteinOTB Aug 26 at 21:18

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.

  • Amazing - thank you! – EinsteinOTB Aug 26 at 23:00
  • thanks again - my vote is not counted but i did my part – EinsteinOTB Aug 26 at 23:11
  • 1
    @EinsteinOTB, If you look at your reputation, page, you'll see you got as +2 for accepting the answer and a +5 for my upvote of your question. Click the arrow next to... Batch read file name and change content creation date on your reputation page to expand it to see what makes up the +15 on the question so far. – user3439894 Aug 26 at 23:19
  • 2
    Let date do the formatting- date -j -f "%Y-%m-%d %H.%M.%S" "${f%.*}" +"%Y%m%d%H%M.%S" – fd0 Aug 27 at 13:48
  • 1
    For those wanting to use the suggestion by fd0, replace what's inside of the Command Substitution command $(...) with his suggested code. In other words remove the sed command, replacing it with the date command mentioned in the comment by fd0. – user3439894 Aug 27 at 14:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .