Renaming .jpg files in subdirectories without changing the creation date (on a MAC)

2

I have a bunch of JPEG files with exactly the same name (i.e. "orig.jpg") each in a seperate subdirectory. Each subdirectory has a unique name (e.g. xplmz3nc5n, tyrn5m6ktv, etc...).

I want to rename the jpegs based on their creation date/time (e.g. 20120629_142536.jpg, etc..).

I was able to use photoshop to batch rename each file with a unique identifier. The key feature that allowed this was photoshop's ability to "include all subdirectories" in a batch process. I was hoping to be able then use exiftool to rename the files to include the creation date (for easy cataloging). Unfortunately, the photoshop batch rename process rewrites the creation date of the file to today's date...

Any suggestions on a way to batch rename the files in a series of subdirectories using, say, terminal commands?

EDIT

The answer here and got the following result in Terminal

cd ~/foo
for dir in *; do 
    t=`stat -c %y "$dir" | awk '{print $1"-"$2}' | 
       cut -d ":" -f 1,2 | sed 's/://'`
    mv "$dir" "$t"_"$dir";
done

and got

stat: illegal option -- c usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...] stat: illegal option -- c usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...] stat: illegal option -- c usage: stat [-FlLnqrsx] [-f format] [-t timefmt] [file ...]

(i.e. I tried two different methods...).

geordie

Posted 2015-01-09T13:04:28.967

Reputation: 121

have you tried anything yourself? – suspectus – 2015-01-09T13:30:40.113

"but won't work in Darwin.." Why do you say that? What did you try exactly, and what were the results? – Ƭᴇcʜιᴇ007 – 2015-01-09T14:58:52.537

I'm really at a loose end with this. Please post an answer if you know how this would be done. Thanks. – geordie – 2015-01-09T22:38:26.047

1Graphic Converter (shareware, not free, but might have a free trial) has some GREAT rename options. I use this ALL the time to manage my digital photos. If you're not a programmer, I'd try to get a tool that does this for you. (I am a programmer, and I still use "GC" for this kind of thing!) – jimtut – 2015-01-10T18:59:57.690

Answers

2

One possibility using the EXIF creation date would be (untested but should work):

  • move all your files into the same directory, renaming them to a unique name (e.g. the name of the containing directory plus the .jpg suffix)

    cd ~/foo
    for i in */; do
      # moves the file (supposedly named orig.jpg) in current directory
      # renaming it to the name of the containing sub directory
      mv ${i}orig.jpg ./`basename $i`.jpg
      # removes the subdirectory, assuming it is now empty
      rmdir $i;
    done
    

    If the files are not always named the same way, but there is only a single file (with name ending in .jpg) in the subdirectory, you can of course replace the mv command with:

      mv ${i}*.jpg ./`basename $i`.jpg
    
  • then rename them using exiftool:

    exiftool -d %Y%m%d_%H%M%S.jpg "-filename<CreateDate" ~/foo
    

    This assumes that no files will have the same creation time down to the seconds level. If there is a risk of filename collision, you can use a variant that adds a suffix to the file name in case of a duplicate name:

    exiftool -d %Y%m%d_%H%M%S%-c.jpg "-filename<CreateDate" ~/foo
    

More info about the renaming function of exiftool here: http://www.sno.phy.queensu.ca/~phil/exiftool/filename.html

Ale

Posted 2015-01-09T13:04:28.967

Reputation: 920

I get the following error: mv: rename ff76e77ec7438371b42fc5027ad00486//orig.jpg to ./.jpg: No such file or directory – geordie – 2015-01-09T23:22:12.473

Ah... didn't consider that directory names would end with /, was working on Linux but not necessarily on MacOS... updated with an improved version. I don't have a Mac around now to test, unfortunately. – Ale – 2015-01-10T00:07:24.943

btw did you check if ff76e77ec7438371b42fc5027ad00486/orig.jpg actually exists? – Ale – 2015-01-10T00:14:26.260

Yes, I checked. There appears to be a syntax issue with your new edited code. it tries to find dirname/dirname.jpg and says there is no such file. It might need someone with a mac to test properly. Thanks for trying. – geordie – 2015-01-10T01:07:35.210

Are you using bash as a shell? – Ale – 2015-01-10T09:21:12.337

1

Unfortunately, OSX does not have the GNU tools but instead, it's core utilities are forks of the BSD versions. This means that many command line answers that you find for Linux won't apply. Either because the relevant options are missing or because they're different.

I don't have an OSX machine to test this on but based on the OSX man pages for stat and date, this should do what you need:

find . -name orig.jpg | 
    while read file; do
     echo mv "$file" "$(date -jf "$(stat -f '%m' "$file")" +%Y%m%d_%H%M%S)".jpg
    done

If your directory names can contain spaces or other strange characters, use this instead:

find . -name orig.jpg -print0 | 
    while IFS= read -r -d '' file; do
     echo mv "$file" "$(date -jf "$(stat -f '%m' $file)" +%Y%m%d_%H%M%S)".jpg
    done

That will just print the commands that will be run. If they are correct, remove the echo and run it again to actually rename the files. As I said, I can't test this since I don't have access to an OSX machine so you might have to tweak it. Have a look at the man pages I linked to (or run man stat on your machine). I am not sure that OSX's date can deal with the output of stat -f '%m', if not, let me know and I'll try and help.

Explanation

  • find . -name orig.jpg : recursively find all files called origin.jpg in the current folder.
  • while read file; ... ; do : this will save each of the file names found by find as $file and then run the next commands on each of them.
  • stat -f '%m' $file : this should show the modification time of the file in a human-readable format.
  • $(date -jf "DATE" +%Y%m%d_%H%M%S) : print the date given by DATE as YYMMDD_HHMMSS. Since we are giving it the output of stat -f '%m' $file, that will print the date that the file was modified.
  • mv "$file" "$(date -jf "$(stat -f '%m' $file)" +%Y%m%d_%H%M%S)".jpg : rename $file to the date returned by date and .jpg.

The equivalent command on Linux is:

find . -name orig.jpg | 
    while read file; do 
        echo mv "$file" "$(date -d "$(stat -c '%y' $file)" +%Y%m%d_%H%M%S)".jpg
   done

terdon

Posted 2015-01-09T13:04:28.967

Reputation: 45 216