Move images/videos to CameraMake/CameraModel/Year/Month/Day tree

Started by SampsonF, February 26, 2018, 01:38:05 PM

Previous topic - Next topic

SampsonF

How can I move images/videos to Make/Model/Year/Month/Day tree, and rename all file extension to lower case.

And only when file already exist, auto append a counter.

I am using Fedora 27.

Phil Harvey

Try this:

exiftool '-testname<${make;}/${model;}/${CreateDate}/%f%-c.%le' -d %Y/%m/%d -r DIR

If you are happy with the results, then replace "testname" with "filename" to actually do the renaming.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

SampsonF

Thank you very much!

What will happen if the media file do not have the $make or $model defined?

When to use $datetimeoriginal vs $CreateDate ?

Phil Harvey

I used CreateDate because videos tend not to have datetimeoriginal, but you can use multiple arguments with different date/time tags.  See here for some examples.  The last valid one takes precedence. The -p option documentation explains what happens when a tag is missing:

            If a specified tag does not exist, a minor warning is issued and
            the line with the missing tag is not printed.  However, the -f
            option may be used to set the value of missing tags to '-' (but
            this may be configured via the MissingTagValue API option), or the
            -m option may be used to ignore minor warnings and leave the
            missing values empty.
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

SampsonF

Thank you Phil!

I need to read and test before using this -p option.

Currently, I am using this as the 1st move command of my library:

exiftool -r -d %Y/%Y%m/%Y%m%d '-directory<${make;}/${model;}/$createdate' '-directory<${make;}/${model;}/$datetimeoriginal' DIR

Then I find out some files have GPSDateTime but none of CreateDate nor DateTimeOriginal.

And further, some files do not have Make nor Model.

How can I write a single command to do the follow:
Use GPSDateTime, DateTimeOriginal, CreateDate in order of preference.
Use Make/Model if defined.
To produce a result tree like:
Make/Model/YY/YYmm/YYmmdd
YY/YYmm/YYmmdd


Phil Harvey

Try this:

exiftool -r -d %Y/%Y%m/%Y%m%d '-directory<$createdate' '-directory<${make;}/${model;}/$createdate' '-directory<${make;}/${model;}/$datetimeoriginal' DIR

I didn't imply that you should use the -p option -- it is just that the advanced formatting feature is explained there.

But I thought you wanted a copy number added to the file name for duplicate files, and a lower-case extension.  This is why I set FileName instead of Directory.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

SampsonF

Hi Phil,

Thank you very much for your replies!  I am sorry if I am not clear enough.

I want to do  it all:
- change EXT to lower case
- append copy number when filename conflicts at destination folder
- sort images into make/model/date if make/model is defined, otherwise sort into date only
- sort into date if not defined
- trust GPSDateTime > DateTimeOriginal > CreateDate > FileModifyTime
- some images received by Whatsapp have IPTCDigest defined.  I want to  sort those under WA/date folder.

I am trying to use:

# Pass 1 - sort into make/mode/date or date tree
exiftool -d %Y/%Y%m/%Y%m%d \
   '-filename<${createdate}/%f%-c.%le' \
   '-filename<${make;}/${model;}/${createdate}/%f%-c.%le' \
   '-filename<${make;}/${model;}/${datetimeoriginal}/%f%-c.%le' \
   -r DIR 

# Pass 2 - sort into Whatsapp/date tree if IPTCDigest defined
exiftool -d %Y/%Y%m/%Y%m%d \
   -if '${IPTCDigest}' \
   '-filename<Whatsapp/${FileModifyDate}/Whatsapp-%f%-c.%le' \
   -r DIR
# Pass 3 - sort remaining files based on FileModifyDate
exiftool -d %Y/%Y%m/%Y%m%d \
   '-filename<${FileModifyDate}/%f%-c.%le' \
   -r DIR

I would like to know if I can do the above 3 passes in one go.

Thanks in advance!

Phil Harvey

Try this:

exiftool -d %Y/%Y%m/%Y%m%d \
   '-filename<${FileModifyDate}/%f%-c.%le' \
   '-filename<Whatsapp/${FileModifyDate}${IPTCDigest;$_=""}/Whatsapp-%f%-c.%le' \
   '-filename<${createdate}/%f%-c.%le' \
   '-filename<${make;}/${model;}/${createdate}/%f%-c.%le' \
   '-filename<${make;}/${model;}/${datetimeoriginal}/%f%-c.%le' \
   -r DIR


Basically, you just sort the assignments in the reverse order of priority, and the last valid assignment takes precedence.  Here the only trick was making one assignment valid only if IPTCDigest exists, without inserting IPTCDigest into the FileName.

Again, you can test this with TestName before setting all the FileName's.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

SampsonF

That's is a great trick to learn!

Thank you very much Phil, it works like a charm!


SampsonF

One more question:

When I run the command, I always run exiftool at the Target folder.

Can I specified a Target folder in the command line as option, so that images in the Source folder will still be moved?

Phil Harvey

You can specify a target directory in each FileName argument (eg. '-filename<SOME_TARGET_DIRECTORY/${FileModifyDate}/%f%-c.%le')

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

SampsonF

Thank you for the reminder, Phil!

I am actually using this without realizing it!  Sorry for the dumb questions.

Endless questions:

In the Make / Model strings, the manufacturers are using different Upper/Lower cases.  Some with '.' and some without.

How can I manually provide a static mapping, such that all new sortings will always be using a "mapped" folders for the Make/Model tags?

Phil Harvey

There are examples in this forum of people doing similar things.  Here is an old one that still applies.  Basically, a technique is to create a user-defined Composite tag to translate the camera model name into anything you want.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

SampsonF

Thank you very much Phil!

Now I have a immediate need to learn custom tags.

SampsonF

Hi Phil,

Thank you very much, I have some progress.  And more questions.

Following your links, I am trying with the following:
MyModel => {
         Require => {
            0 => 'Model',
         },
         ValueConv => '$val[0]',
         PrintConv => {
          'iPhone 5s' => "iPhone 5S",
          #'iPhone 6,2 - 8.0.2' => "iPhone 6",
          #'iPhone 6,2 - 8.1.1' => "iPhone 6",
          #'iPhone 6,2 - 8.1.2' => "iPhone 6",
          #'iPhone 6s' => "iPhone 6S",
          #'iPhone 6s Plus' => "iPhone 6S Plus",
         },
      },

When the original Model is indeed "iPhone 5s", MyModel return "iPhone 5S" correctly.  But for original Modes not defined in my table yet, like "iPhone 6s", MyModel returned "Unknown (iPhone 6s)".

How to make MyModel return the original Model if it is not defined in my custom list?