27

If I rename images via exiv to the exif date time, I do the following:

find . -iname \*jpg -exec exiv2 -v -t -r '%Y_%m_%d__%H_%M_%S' rename {} \; 

Now it might happen that pictures have exactly the same timestamp (including seconds). How can I make the filename unique automatically?

The command should be stable in the sense that if I execute it on the same directory structure again (perhaps after adding new pictures), the pictures already renamed shouldn't change and if pictures with already existing filenames are added the new filenames should be unique as well.

My first attempt was just to leave the original basename in the resulting filename, but then the command wouldn't be stable in the sense above.

3
  • 1
    Extract the timestamp, build the filename, check for existing filename, modify (add suffix or similar) if present, then mv the file. Commented Oct 1, 2017 at 7:15
  • Is there also a more direct way by adding an option to the exiv2 command? Commented Oct 1, 2017 at 10:07
  • So the answer using exiftool would be something like: exiftool '-filename<createdate' -d %Y_%m_%d__%H_%M_%S%%-c.%%le "-filemodifydate<createdate#" -r -progress .. Maybe you could turn your comment to an answer. Commented Oct 2, 2017 at 5:59

5 Answers 5

44

You may want to try jhead instead which does that out-of-the-box (with a, b... z suffixes allowing up to 27 files with the same date) and doesn't have the stability issue mentioned by @meuh:

find . -iname '*jpg' -exec jhead -n%Y_%m_%d__%H_%M_%S {} + 

Or using exiftool (example in man page):

exiftool -ext jpg '-FileName<CreateDate' -d %Y_%m_%d__%H_%M_%S%%-c.%%e . 

(here with %-c being a numerical suffix starting with -; added if the file already exists)

(Contributed to answer and corrected from the comments):

In case you want to preserve the original filename, simply add _%%f:

 exiftool -ext jpg '-FileName<CreateDate' -d %Y_%m_%d__%H_%M_%S%%-c_%%f.%%e . 
2
  • 1
    In case you want to preserve the original filename, simply add _%f: exiftool -ext jpg '-FileName<CreateDate' -d %Y_%m_%d__%H_%M_%S%%-c_%f.%%e . Commented May 13, 2021 at 8:29
  • 1
    For recorsively rename do: exiftool -r -ext jpg '-FileName<CreateDate' -d %Y_%m_%d__%H_%M_%S%%-c.%%e . Commented Dec 21, 2021 at 9:50
7

My version of exiv2 (0.25 001900) will ask interactively what to do when the filename already exists.

exiv2: File `./2013_06_19__14_03_13.jpg' exists. [O]verwrite, [r]ename or [s]kip? 

By adding option -F it will instead automatically add an extra _1 (or _2 etc) to the name.

Renaming file to ./2013_06_19__14_01_53_1.jpg, updating timestamp 

If the command is run a second time it says:

This file already has the correct name 

and does nothing, but it gets confused if there is the _1 part, and will rename it _2. It will toggle like this in a non-destructive way on each run. You can ignore this if you like, or change your find pattern to ignore files matching the date pattern with an _ part.

For example, the regex pattern for the date format begins [0-9]{4}_[0-9]{2}_.... To simplify, I'll just look for a mix of 20 characters from the set 0..9 and _, which is regex [0-9_]{20}. To this the suffix of _ followed by at least 1 digit to look for is _[0-9]{1,}.jpg. Since the regex has to match the whole path, and not just the basename, the final regex including the directory is .*/[0-9_]{20}_[0-9]{1,}.jpg.

So you can use a find like:

find . -regextype posix-extended ! -iregex '.*/[0-9_]{20}_[0-9]{1,}.jpg' -iname '*.jpg' ... 
0
6

Exiv2 can handle it on its own. I also spent a lot of time looking for help on this, until I went to see the exiv2 manual. The -F option solves this problem.

exiv2 -r'%Y_%m_%d__%H_%M_%S' -F *.jpg 

It will append a _N at the end if the file already exist.

And for thoses who are looking for an option that allow create folder.

exiftool -r '-FileName<DateTimeOriginal' -d %Y/%m/%d/%%f%%-c.%%e * 
0

The pyrenamer will not work on my new installed Ubuntu 16.04, therefore I have to find another way to solve this problem too.

I have files such as IMG_0001.JPG, IMG_0002.JPG,... in one folder. Check this site, https://stackoverflow.com/questions/917260/can-var-parameter-expansion-expressions-be-nested-in-bash

Install the "exiv2" first, and I wrote the following command line:

for img in $(ls *.[Jj][Pp][Gg] 2> /dev/null); do exiv2 -r'%Y%m%d_%H%M%S_'"$(tmp=${img%%.*};echo ${tmp##*_})" rename "$img" ; done

The output filenames are YYYYMMDD_HHMMSS_0001.JPG, YYYYMMDD_HHMMSS_0002.JPG,... etc. Even the photos were taken at the same second, the original photo serial number will make the difference.

0

This worked for me:

find . -iname '*jpg' -exec jhead -n%Y_%m_%d__%H_%M_%S {} + 

or use exifoo which is a simple app without need of the terminal.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. Commented Mar 26 at 0:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.