Messy library. Too many copies. Several renames

Started by smaiderman, January 25, 2024, 12:01:08 PM

Previous topic - Next topic

smaiderman

Hi there!
Thank you for creating this tool and letting us ask.

I have a really big library. So many photos and videos, some of them with exif and otrher without exif.
I wonder if there is a command to copy the FileModifyDate, to be in the exif in all the relevant tags.

For example, i have a photo without exif that gives this info


How can I make, in a really big folder, with lots of subfolders, to edit only the files that dont have any exif info, to take the earliest date (I think "FileModifyDate" is the one), and write it in all the date fields in the exif?


My final goal is to have a single copy of every photo/video, with all the possible metadata (mainly gps and date)


Thank you so much!

Phil Harvey

If you are on Windows or Mac, FileCreateDate is available, and may be earlier than FileModifyDate.

To so what you ask, you can do this (quoting is for Windows CMD shell):

exiftool "-alldates<filecreatedate" -if "not $exif:all" -P DIR

The -P is necessary to preserve the filesystem date/time information.  You can add -r to recurse into subdirectories, and -overwrite_original to prevent preserving the "_original" backup files.

"AllDates" is a shortcut for the 3 common EXIF date/time tags (DateTimeOriginal, ModifyDate and CreateDate).

The -if condition will cause files containing any EXIF to be ignored.

- 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 ($).

smaiderman

Great! Thank you-.

Does filecreatedate remain the same even if you copy and paste the file to a new location? or will it change to the "paste date"?

I'm on Windows

Phil Harvey

It should remain if you use the -P option.  But you should probably test to be sure because I can't guarantee that for some filesystems like remote file servers for example.

- 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 ($).

StarGeek

Quote from: smaiderman on January 25, 2024, 02:06:15 PMDoes filecreatedate remain the same even if you copy and paste the file to a new location? or will it change to the "paste date"?

Yes

Seriously, I've had times when the FileCreateDate was correct and others when the FileModifyDate was correct.  These files had passed through multiple external flash drives and hard drives, as well as through other devices. I've never been observant enough to notice exactly when things have changed.  Both values should stay the same when copying/moving through the Windows desktop. Copying through the command line will probably change the date for both unless you use Robocopy with the /DCOPY:T option.

I find conflicting answers when SuperUser.com so there are probably enough edge cases to make it a problem.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

...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 ($).

smaiderman

Thank you both.
So, I guess I have to check manually, and its going to take me a looooong time.

Thanks again :)

smaiderman

#7
I think I'm having an idea to make this easier.
Could exiftool add a prefix to files that have exif information and not modify anything else (I think this is -P )?

For example,

FOLDER
-1.jpg (has exif info)
-2.jpg (doenst have exif info)
-1.mov (has exif info)
-1.mkv (doesn't have exif info)

make it be

FOLDER
-(e)1.jpg
-(ne)2.jpg
-(e)1.mov
-(ne)1.mkv

?

This way, I could simply know what files I have to check if FileCreateDate or FileModifyDate is the earliest one





Also, another doubt. If I use:

exiftool '-filename<CreateDate' -d %Y%m%d_%H%M%S%%-c.%%le -r /filelocation

This will only work in all files (photo, video) WITH exif info?

Phil Harvey

#8
How about running 2 commands instead of doing this manually:

1. exiftool "-alldates<filecreatedate" -if "not $exif:all and $filecreatedate le $filemodifydate" -P DIR

2. exiftool "-alldates<filemodifydatedate" -if "not $exif:all and $filemodifydate lt $filecreatedate" -P DIR

- Phil

Edit: Fixed tt formatting
...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 ($).

smaiderman

#9
I guess it is the correct way, but as I'm just starting to know Your software, I would like to understant what we are doing, so let me try-

1. exiftool "-alldates<filecreatedate" -if "not $exif:all and $filecreatedate le $filemodifydate" -P DIR

This will, for every file in DIR that has no exif info, create the 3 main dates in the exif tag with the filecreatedate value, AND, only do this if filecreatedate is less or equal than filemodifydate (I found that le for comparisons, and Returns true if the first value is less than or equal to the second value.)

If this is true, how does the le compares dates data? It is not an absolute number. Will it work anyway?


2. exiftool "-alldates<filemodifydatedate" -if "not $exif:all and $filemodifydate lt $filecreatedate" -P DIR

This will, for every file in DIR that has no exif info, create the 3 main dates in the exif tag with the filemodifydate value, AND, only do this if filemodifydate is less (but not equal) than filecreatedate second value.


3. Can I add -r to do this to all subfolders? Where in the sentence whould this go?


4. Should I run the first command, and then the second? or is it the same line in CLI?


Thank you so much! Such a powerfull tool

Phil Harvey

You understand what is happening.

Quote from: smaiderman on January 26, 2024, 10:13:36 AMIf this is true, how does the le compares dates data? It is not an absolute number.

The "le" operator is a string comparison.  ASCII string comparisons work for standard EXIF-format date/time values.

Quote3. Can I add -r to do this to all subfolders? Where in the sentence whould this go?

Yes.  Anywhere except between -if and its condition.

Quote4. Should I run the first command, and then the second? or is it the same line in CLI?

You need to run the commands separately.  They are 2 separate commands.

- 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 ($).

smaiderman

What if the file contains exif that has some fields but no exifdates?

I tried with
exiftool "-alldates<filemodifydate" -if "not $exif:createdate and $filemodifydate lt $filecreatedate" -P

exiftool "-alldates<filemodifydate" -if "not $exif:alldates and $filemodifydate lt $filecreatedate" -P

and also doing the same in the createdate le modifydate script, but it didnt change anything. Still no dates in exif

Phil Harvey

#12
Very close.  The problem is that the -if will fail with a minor warning if any of the requested tags don't exist.  Add the -m option to ignore this minor warning and either of your commands should work.  (You see this warning by adding the -v option.)

- Phil

Edit: Actually, something funny is happening here.  The -m fixes it, but I didn't think it should be necessary...  I'll look into this.
...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 ($).

Phil Harvey

I was fooling myself.  Your command should work if FileModifyDate is before FileCreateDate (which should actually never be the case).

- 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 ($).

StarGeek

Quote from: Phil Harvey on January 26, 2024, 01:30:36 PMYour command should work if FileModifyDate is before FileCreateDate (which should actually never be the case).

Windows laughs at your assertion.

C:\>exiftool -G1 -a -s  -r -fast3 -if "$FileModifyDate lt $FileCreateDate" -aaa Y:\Pictures\Camera_Pictures\SDCC
<snip>
  279 directories scanned
20057 files failed condition
63450 image files read

So, 43,393 files where FileModifyDate is less than FileCreateDate.  This dates back to my first digital camera from 1998.  Though everything from 2010 onward is duplicated, a jpeg and RAW file.

Nearly all of them would have just been copying through the desktop, not through the command line.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).

Phil Harvey

Hehe.  Odd.  On Mac it isn't such a free-for-all. ;)

- 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 ($).

smaiderman


smaiderman

Quote from: Phil Harvey on January 25, 2024, 12:52:32 PM"AllDates" is a shortcut for the 3 common EXIF date/time tags (DateTimeOriginal, ModifyDate and CreateDate).

Is there a shortcut to FileModifyDate and FileCreateDate (i dont care about FileAccessDate, but its ok if it changes too). I want to change every date in the file properties, including exif, and I tried with exiftool "-time:All<DateTimeOriginal" without success.

Phil Harvey

The filesystem date/time tags are marked as Unsafe so they aren't updated with Time:All.  You need to do these individually.

- 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 ($).

StarGeek

Quote from: smaiderman on January 27, 2024, 07:12:35 AMIs there a shortcut to FileModifyDate and FileCreateDate (i dont care about FileAccessDate, but its ok if it changes too).

It is possible to create your own shortcuts.  The very first section of the example.config file has details on how to do so and how to create a .ExifTool_config file so it will always be available.

In this post I give some examples of shortcut tags I made and regularly use.  The "Systime" shortcut listed there is what I use to write to the FileCreateDate/FileModifyDate tags at the same time.

Exiftool can't write the FileAccessDate and there really isn't a need to because it will automatically be changed any time the computer ever touches the file. For example, viewing an image will automatically set it to the time that happens.
* Did you read FAQ #3 and use the command listed there?
* Please use the Code button for exiftool code/output.
 
* Please include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).


smaiderman

Quote from: StarGeek on January 27, 2024, 09:57:04 AMIt is possible to create your own shortcuts.  The very first section of the example.config file has details on how to do so and how to create a .ExifTool_config file so it will always be available.

In this post I give some examples of shortcut tags I made and regularly use.  The "Systime" shortcut listed there is what I use to write to the FileCreateDate/FileModifyDate tags at the same time.

Exiftool can't write the FileAccessDate and there really isn't a need to because it will automatically be changed any time the computer ever touches the file. For example, viewing an image will automatically set it to the time that happens.

Thank you  :D

It is harder than my knowledge level, and if you dont mind, I would like to ask some questions.

My main goal is to modify every date in the file info and exif info to the same value (the original one). So, in .ExifTool_config I wrote this

%Image::ExifTool::UserDefined::Shortcuts = (
    MasterDateVideo =&gt; ['exif:CreateDate','exif:DateTimeOriginal','exif:ModifyDate','exif:MediaModifyDate','exif:MediaCreateDate','exif:TrackModifyDate','exif:TrackCreateDate','FileCreateDate','FileModifyDate','XMP:DateTimeOriginal','XMP:CreateDate','XMP:ModifyDate']
    MasterDateFoto =&gt; ['exif:CreateDate','exif:DateTimeOriginal','FileCreateDate','FileModifyDate','exif:ModifyDate','exif:TimeStamp','exif:SubSecDateTimeOriginal','exif:SubSecMoifyDate','exif:SubSecCreateDate','XMP:DateTimeOriginal','XMP:CreateDate','XMP:ModifyDate']
);
#------------------------------------------------------------------------------
1;  #end

1. Would this be ok, and cover most time tags? (I've seen some 'Quicktime:xxx' tags, but I tried to find them in my media and I couldn't.)
2. I've seen some examples using CreateDate instead of exif:CreateDate Which one is correct?
3. In the example that you provide, it is written =&gt, but I've seen you write also => in other forum posts. Which one should I use?

4. Can I delete everything else in the .ExifTool_config file? I only need this shortcut to rewrite all time data fields.

5. In the case that everything is correct, as the file name is .ExifTool_config , do I only need to place it in the same folder as Exiftool.exe ? (I think -config is only used if the name is different than .ExifTool_config)

Thank you very much again

Phil Harvey

There were a few format problems with your config file.  The "&gt;" should be a ">" symbol, and there needs to be a comma after the closing "]" at the end of each line.  You can delete everything else in the config file.  If you name it .ExifTool_config and place it in the same directory as exiftool.exe you don't need to use the -config option.

I would recommend not specifying the "exif:" group.  In fact, most of the tags you specify aren't even EXIF, so this won't work.  If you just want to change existing tags, it is better to not specify the group so all tags of this name will be changed, and add "-wm w" to the command so new tags aren't created.

- 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 ($).

smaiderman

Great. I missed the final commma.
Thanks for the advice. I think I'm getting really close to what I need.

Thank you!
I just made a donation :)

smaiderman

Well.
I managed to create a simple command to do what I was looking for.

The command is the next:

exiftool "-MasterDates<OldestDateTime" -wm w DIR

My .ExifTool_config is:
%Image::ExifTool::UserDefined::Shortcuts = (
    MasterDates => ['DateAcquired','CreateDate','DateTimeOriginal','FileCreateDate','FileModifyDate','ModifyDate','TimeStamp','MediaModifyDate','MediaCreateDate','TrackModifyDate','TrackCreateDate','SubSecDateTimeOriginal','SubSecMoifyDate','SubSecCreateDate','XMP:DateTimeOriginal','XMP:CreateDate','XMP:ModifyDate'],
  );

%Image::ExifTool::UserDefined = (
    'Image::ExifTool::Composite' => {
        # Select oldest date from a number of date tags
        OldestDateTime => {
            Desire => {
                0 => 'FileModifyDate',
                1 => 'MDItemFSContentChangeDate',
                2 => 'FileCreateDate',
                3 => 'MDItemFSCreationDate',
                4 => 'ModifyDate',
                5 => 'CreateDate',
                6 => 'DateTimeCreated',
                7 => 'DateTimeOriginal',
                8 => 'DateAcquired',
                9 => 'MediaCreateDate',
                10 => 'TrackModifyDate',
                11 => 'TreackCreateDate',
                12 => 'XMP:DateTimeOriginal',
                12 => 'XMP:CreateDate',
                12 => 'XMP:ModifyCreateDate',
            },
            ValueConv => q{
                my $oldest = undef;
                for my $date (@val) {
                    next if not defined $date or $date lt '1970:01:02';
                    $date =~ s/[+-]\d{2}:\d{2}$//; # Strip TimeZone
                    if ($date && (!$oldest || $date lt $oldest)) {
                        $oldest = $date;
                    }
                }
                return $oldest;
            },
        },
    },
);

1;

This will check for the majority date time tags in the file (I will add more if I find new ones), take the oldest one, and write it in every date time tag that is present in the file.


As long as I'm writting this message, it comes to my mind that there is going to be a sitouation with the files that dont have exif data. I mean, this solution will modify the dates present in the file information, but there will be files missing exif info.

This is because -wm w is in the command. The problem if I remove it, is that I will create a lot of false tags in every file, and I dont know if it is appropiate.


One solution that comes to my mind is to do,

1st

Add a new Shortcut in .ExifTool_config  "MasterDatesNE" with the most common tags (? Again, I dont know if this is a good practice, but I think I would like the files to have the time data in the exif so I dont have the messy FileCreate/ModifyDate problem that I'm having now )
and use this command:
exiftool "-MasterDatesNE<OldestDateTime" -if "not $exif:all" DIR

And 2nd 
exiftool "-MasterDates<OldestDateTime" -wm w DIR



What do you think?

(I'm enjoying so much. This is like a really hard riddle!)



Phil Harvey

I think I would just go with removing the -wm w.  You will create XMP in JPG files (for CreateDate at least), but that may actually not be a bad idea.  (Actually, I see you've left the XMP tags in here too, so good.)  Note that "SubSecMoifyDate" should be "SubSecModifyDate" in your config file.

- 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 ($).

smaiderman

Thank you. I'll go that way.

edit: had a doubt but already solved it