Renaming .jpg files in subdirectories without changing the creation date (on a MAC)
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 themv
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
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 calledorigin.jpg
in the current folder. -
while read file; ... ; do
: this will save each of the file names found byfind
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 byDATE
as YYMMDD_HHMMSS. Since we are giving it the output ofstat -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 bydate
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