Batch copy metadata from a folder to subfolder

Started by Waexto, October 21, 2017, 08:09:05 PM

Previous topic - Next topic

Waexto

Hello, my scenario is something like this:

C:\<folder>\  <-- contains 100+ JPG images
C:\<folder>\DONE\   <-- contains 100+ JPG images of identical filenames as above

I want to copy the metadata of every JPG images from "C:\<folder>" to "C:\<folder>\DONE". They have the same number of files and also the same filenames. I have many other folders like this.

To accomplish my goal, my Windows 7 CMD line is like this:
for %Z in ("*.jpg") do exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "%~nZ.jpg" "DONE\%~nZ.jpg"

It works and the output is like this after I copy-pasted it into a CMD box:

C:\TEST>for %Z in ("*.jpg") do exiftool.exe -P -overwrite_original -charset utf8
-TagsFromFile "%~nZ.jpg" "DONE\%~nZ.jpg"

C:\TEST>exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "1.jpg"
"DONE\1.jpg"
    1 image files updated

C:\TEST>exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "2.jpg"
"DONE\2.jpg"
    1 image files updated

C:\TEST>exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "3.jpg"
"DONE\3.jpg"
    1 image files updated

C:\TEST>


Again, it works without problems but it takes a very long time to finish especially if the folder contains hundreds of images as ExifTool is executed for every individual image. I believe my CMD line is a "common mistake" (perhaps #4 in Mistakes).

I tried to use ExifTool on its own without the usage of FOR, but I had no luck. These are the closest I could do:

exiftool.exe "*.jpg" -P -overwrite_original -charset utf8 -TagsFromFile . -o DONE
exiftool.exe -ext jpg . -P -overwrite_original -charset utf8 -TagsFromFile . -o DONE


The abort message is like this:

C:\TEST>exiftool.exe -ext jpg . -P -overwrite_original -charset utf8 -TagsFromFi
le . -o DONE
Warning: Error opening file - .
Error: 'DONE/1.jpg' already exists - ./1.jpg
Error: 'DONE/2.jpg' already exists - ./2.jpg
Error: 'DONE/3.jpg' already exists - ./3.jpg
    1 directories scanned
    0 image files updated
    3 files weren't updated due to errors

C:\TEST>


And so, if it is possible, my request is an efficient alternative to my CMD line. Thanks in advance, friends. :)

StarGeek

Try this, you'll find it's MUCH faster.
exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "%-:1D/%F" C:\<folder>\DONE\

Example output:
C:\>exiftool -g1 -a -s -r -xmp:all Y:\!temp\y
======== Y:/!temp/y/Done/testfile.jpg
======== Y:/!temp/y/testfile.jpg
---- XMP-x ----
XMPToolkit                      : Image::ExifTool 10.64
---- XMP-dc ----
Description                     : Here's a description
Title                           : No, Adobe, you're using this wrong
    2 directories scanned
    2 image files read

C:\>exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "%-:1D/%F" Y:\!temp\y\Done\
    1 directories scanned
    1 image files updated

C:\>exiftool -g1 -a -s -r -xmp:all Y:\!temp\y
======== Y:/!temp/y/Done/testfile.jpg
---- XMP-x ----
XMPToolkit                      : Image::ExifTool 10.64
---- XMP-dc ----
Description                     : Here's a description
Title                           : No, Adobe, you're using this wrong
======== Y:/!temp/y/testfile.jpg
---- XMP-x ----
XMPToolkit                      : Image::ExifTool 10.64
---- XMP-dc ----
Description                     : Here's a description
Title                           : No, Adobe, you're using this wrong
    2 directories scanned
    2 image files read


The source for -TagsFromFile is "%-:1D/%F".  This is a variation on the %d/%f substitution you will find detailed under the -w option.  In this case, the addition of -:1 to the %d removes one level of directory from the directory path of the current target file.  So when I'm getting ready to copy tags to Y:/!temp/y/Done/testfile.jpg, it removes the last path level so as to look in the Y:/!temp/y directory.  The %F is the filename for the current target file.  Since the F is capitalized, it will include the extension.  A lowercase f would exclude the extension and you would have to add the extension you wanted if it was different or .%e if it was the same.
* 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).

StarGeek

Looking at your own attempts, I think I need to point out a difference in the way Exiftool and your command line works.

Here's an example file tree.  Notice that there's a file in the current directory that's not in Done and vice Versa.
C:\>tree Y:\!temp\y /F
Folder PATH listing for volume DrivePool
Volume serial number is blah-blah-blah
Y:\!TEMP\Y
│   Only_In_CurrentDir.jpg
│   testfile.jpg
│   
└───Done
        Only_In_DoneDir.jpg
        testfile.jpg


You CMD line grabs the name of each file in the current directory.  In this case, Only_In_CurrentDir.jpg and testfile.jpg.  It then attempts to copy the tags from these to files into matching files in DONE, with Only_In_CurrentDir.jpg obviously failing.

Exiftool is working the other direction.  It's reading the target directory, DONE, and then looking for matching files in the parent directory.  So it will copy tags from testfile.jpg to DONE/testfile.jpg, then look for Only_In_DoneDir.jpg but won't find it, throwing an error at that point.  It won't ever see Only_In_CurrentDir.jpg because it's not processing that directory, it's processing DONE directory.

Another thing that I should mention is that you may want to add -all:all to your command (-TagsFromFile "%-:1D/%F" -all:all C:\<folder>\DONE\).  Without any specific tags, it is the same as if you had specified -all.  This will copy tags from the source file to their preferred location in the target file (see second paragraph under the -TAG option).  These means some tags may not get copied to their original places.  For example, XMP:DateTimeOriginal would get copied to EXIF:DateTimeOriginal and not duplicated in XMP:DateTimeOriginal.  This probably wouldn't change anything if no metadata had been added to the files before processing them to DONE.
* 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).

Waexto

Thanks! I tested your suggestion on a folder which contains about 600+ images, and it was very fast. The difference in speed compared to my original FOR cmd is night and day. Wow! I modified it a little bit so that the name of the source folder is irrelevant. For now it looks like below. I'll try the -all:all afterwards.
exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "%-:1D/%F" .\DONE\

Which was based on your recommendation:
exiftool.exe -P -overwrite_original -charset utf8 -TagsFromFile "%-:1D/%F" C:\<folder>\DONE\

Also thanks for the additional tips. They're quite intimidating for me for now but I'm very glad for this. I can't thank you enough for being so detailed in your explanation. I'll be saving this page in my hard disk for study and future reference as I don't have a fast and permanent internet connection. Thanks again my friend.  ;D

StarGeek

* 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).

burak

Hi,

I need exactly the same thing but I keep my old and new files in different folders. They are in network drives so putting them in the same folder would take time. How can I do it, if I work with different folders for batch copying the metadata between folders?

StarGeek

Assuming they have the same name
exiftool -TagsFromFile /path/to/source/%f.%e -TAG1 -TAG2 -TAGn /path/to/targetfiles/

Replace the TAG* with the name of the tags you want to copy.  Use -All:All to copy all tags.

Copying tags on a network drive will only be as fast as your connection.  Pretty much the same as if you were copying to/from that drive.
* 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).

burak

Thanks a lot. I tried with a single file and it worked.

I have two more questions if you don't mind:
1- When I run the tool, I see there are copies of target files without tags along with tagged target files. Is there a way to prevent creating copies without tags? I add tags to video files and some are big. I do not want them to be copied.
2- Is it possible to carry tags between different container types? I have .mov, .mkv and .mp4 files that I want to convert all to one type (.mkv or .mp4).

StarGeek

Quote from: burak on October 12, 2020, 05:45:43 AM
1- When I run the tool, I see there are copies of target files without tags along with tagged target files. Is there a way to prevent creating copies without tags? I add tags to video files and some are big. I do not want them to be copied.

You can suppress the creation of backup files with the -overwrite_original option.

Quote2- Is it possible to carry tags between different container types? I have .mov, .mkv and .mp4 files that I want to convert all to one type (.mkv or .mp4).

Exiftool cannot edit mkv files.  It will copy what tags it can from an mkv but not all mkv tags have a corresponding tag in a mp4.  For example, some data in mkv files is saved as a KEY:VALUE pair.  Exiftool cannot copy this directly.

To copy between different file types, you would change the %e in the command.  That stands for the extension.  For example, to copy to an mp4 from a mov file with the same name
exiftool -TagsFromFile /path/to/source/%f.mov -TAG1 -TAG2 -TAGn /path/to/targetfiles/
* 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).

burak

Worked like a charm! Thank you so much.

I will probably than stick with .mp4 format for my converted videos.

waed242

I have almost exactly the same use case as OP, albeit with several thousand photos. The destination folder is in Onedrive but the first upload from my phone did not bring any meta data. When I view the same folder via USB; the metadata is there, but I dont want to have to reupload the whole lot to the cloud as the images themselves obviously take up the bulk of the data... So copying just the metadata (mainly "date taken") to the onedrive folder would be ideal... Same number of images... same name....then onedrive only need upload the 'changes'.

I am completely new to Exiftool and dont quite understand the below. Would anyone be able to spell it out a for a beginner like me?

Thank you so much in advance!!!

StarGeek

In your case, you would probably want to copy AllDates, which is a shortcut for the three major EXIF tags, DateTimeOriginal, ModifyDate, and CreateDate.  Assuming Windows, those are the three tags that Windows is most likely to draw from to fill the "Date Taken" property (which isn't the actual name of a tag).

But depending upon the source of the files, they may be such that they don't have embedded metadata (such as WhatsApp images).  In that case, you would also want to copy the file system timestamps.

Your command would be along the lines of
exiftool -TagsFromFile /path/to/USBFolder/%f.%e -AllDates -FileCreateDate -FileModifyDate /path/to/OneDriveFolder/

This assumes the filenames will be the same in both directories.

All you have to do is replace the "/path/to" parts with the actual paths to the files.
* 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).

waed242

Thank you @StarGeek for your response; much appreciated.