Creating symlinks for each XMP keyword / substring in a tag

Started by robert_f, April 23, 2022, 05:20:40 AM

Previous topic - Next topic

robert_f

Alright, so I'm sure the solution is simple, but after an hour of Googling I just cannot find how to resolve what seemed a straightforward task.

Because XMP tags have atrocious support, I've decided to workaround it via directories and symlinks. So far I've managed to type up this:

exiftool -r -ext png . '-symlink</home/user/Pictures/.tags/$keywords/%f'

But this doesn't work for any picture with multiple tags; exiftool simply treats the entire thing as a single string.

(Incidentally, would there be a method to remove symlinks if the file no longer contains the keyword that doesn't involve some complex bash piping?)

Thanks!

StarGeek

Off hand I don't see any easy way of doing this.  What would be required is a way to loop through the list of keywords and copy each individually to SymLink.

Maybe Phil can come up with some magic but the only way I can think of is to run exiftool multiple times and use the -listItem option.  First figure out the maximum number of keywords and then run exiftool that many times, incremeing the INDEX for each

exiftool -if "$keywords" -listItem 0 -r -ext png . '-symlink</home/user/Pictures/.tags/$keywords/%f'
exiftool -if "$keywords" -listItem 1 -r -ext png . '-symlink</home/user/Pictures/.tags/$keywords/%f'
exiftool -if "$keywords" -listItem 2 -r -ext png . '-symlink</home/user/Pictures/.tags/$keywords/%f'
...
exiftool -if "$keywords" -listItem <max-1> -r -ext png . '-symlink</home/user/Pictures/.tags/$keywords/%f'
* 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).

Alan Clifford

I used keywords before I remembered keywords are iptc.  But shouldn't matter.

exiftool -keywords x-s1_3892.jpg
Keywords                        : Barbados, Chancery Lane, swamp


#!/bin/bash

filename="x-s1_3892.jpg"

echo "<${filename}>"

# keywords=$(exiftool -s3 -keywords x-s1_3892.jpg | tr , "\n" | tr -d " ")
keywords=$(exiftool -s3 -keywords "${filename}" | tr , "\n" | tr -d " ")

echo "<${keywords}>"

for i in ${keywords}; do

  echo "<${i}>"
  ln -s "${filename}" "${i}"

done



cellini:test alan$ ls -l
total 12448
lrwxr-xr-x  1 alan  staff       13 23 Apr 19:49 Barbados@ -> x-s1_3892.jpg
lrwxr-xr-x  1 alan  staff       13 23 Apr 19:49 ChanceryLane@ -> x-s1_3892.jpg
-rwxr--r--  1 alan  staff      309 23 Apr 19:48 keywordlink.sh*
lrwxr-xr-x  1 alan  staff       13 23 Apr 19:49 swamp@ -> x-s1_3892.jpg
-rw-r--r--  1 alan  staff  6365223 23 Apr 19:24 x-s1_3892.jpg




robert_f

Quote from: StarGeek on April 23, 2022, 12:06:28 PM
Off hand I don't see any easy way of doing this.  What would be required is a way to loop through the list of keywords and copy each individually to SymLink.

Darn. So much for trying to optimize my bash script.  :(
Just for future knowledge though, this won't create incorrectly sorted and/or dead symlinks if the file has less tags than the max, right?

StarGeek

Quote from: robert_f on April 23, 2022, 04:16:21 PMJust for future knowledge though, this won't create incorrectly sorted and/or dead symlinks if the file has less tags than the max, right?

To avoid that, I included the -if option.  If you use the -listItem option beyond the maximum number of entries, it will return undefined and skip that file.

Example. Here I try to copy the first (0) keyword to Description.  Works correctly.  Clear description and try to copy the fifth keyword (4), which doesn't exist.  Throws a warning and nothing is copied.

C:\>exiftool -G1 -a -s -Keywords -Description y:\!temp\Test4.jpg
[IPTC]          Keywords                        : Zero, One, Two, Three

C:\>exiftool -P -overwrite_original -listItem 0 "-Description<Keywords" y:\!temp\Test4.jpg
    1 image files updated

C:\>exiftool -G1 -a -s -Keywords -Description y:\!temp\Test4.jpg
[IPTC]          Keywords                        : Zero, One, Two, Three
[XMP-dc]        Description                     : Zero

C:\>exiftool -P -overwrite_original -Description= y:\!temp\Test4.jpg
    1 image files updated

C:\>exiftool -P -overwrite_original -listItem 4 "-Description<Keywords" y:\!temp\Test4.jpg
Warning: No writable tags set from y:/!temp/Test4.jpg
    0 image files updated
    1 image files unchanged

C:\>exiftool -G1 -a -s -Keywords -Description y:\!temp\Test4.jpg
[IPTC]          Keywords                        : Zero, One, Two, Three


Remember to change double quotes into single quotes for linux/Mac.

But expanding upon Alan's idea, it might be better to script it.  Except rather than running exiftool on every file (see Common Mistake #3), dump the full list into a temp file.  For example, run
exiftool -p "$Filename,$Keywords" /path/to/files/
Then extract the file name, tr the rest, and run the ln loop.
* 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).