perl code question

Started by StarGeek, February 21, 2016, 07:21:59 PM

Previous topic - Next topic

StarGeek

I'm making a command so that I can replace base keywords in HierarchicalSubject.  I have this command which seems to be working:
Exiftool -sep "##" "-HierarchicalSubject<${HierarchicalSubject;my $needle=quotemeta('OriginalKeyword');my @m = split/##/;s/(^|\|)${needle}$/$1NewKeyword/ for @m;$_=join('##',@m)}" Files

I thought I could combine some of the separate commands like this:
Exiftool -sep "##" "-HierarchicalSubject<${HierarchicalSubject;my $needle=quotemeta('OriginalKeyword');$_=join('##',s/(^|\|)${needle}$/$1NewKeyword/ for split/##/)}" Files
But that throws a "Warning: syntax error for HierarchicalSubject".  What is my mistake on the second command, so I can avoid it in the future.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Phil Harvey

Both expressions are doing something I don't understand.  The substitution expression (s///) returns an integer (in scalar context anyway -- I don't know what it returns in list context).  I'll take a closer look and show you how I'd do it tomorrow when I get a bit more time.

- 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

I picked up the substitution expression from this PerlMonks post.

My test case for the HierarchicalSubject is "Hierarchical|Subject|AnotherKeywords2, People|Jane, People|John, Keyword, Jane" where I want to change both of the Jane keywords into something else, keeping the hierarchy when there is one.  Maybe it's an unusual case, but I was trying to capture all possibilities. 

Example working output of the first expression:
c:\>exiftool -hs X:\!temp\Test3.jpg
Hierarchical Subject            : Hierarchical|Subject|AnotherKeywords2, People|Jane, People|John, Keyword, Jane

c:\>Exiftool -sep "##" "-HierarchicalSubject<${HierarchicalSubject;my $needle=quotemeta('Jane');my @m = split/##/;s/(^|\|)${needle}$/$1Mary/ for @m;$_=join('##',@m)}" X:\!temp\Test3.jpg
    1 image files updated

c:\>exiftool -hs X:\!temp\Test3.jpg
Hierarchical Subject            : Hierarchical|Subject|AnotherKeywords2, People|Mary, People|John, Keyword, Mary


I had originally thought I could do something similar to the join map split construct I had done in posts like this but when it returned an error, I couldn't figure out where the problem was.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Hayo Baan

Hi Stargeek,

Interesting! In this case, however, why do you split the list at all? I think you can do the replacement in one go with something like this: s/(^|##|\|)Jane($|##|\|)/$1Mary$2/g
(Note: haven't been able to test this, but I'm quite certain this should work)
Hayo Baan – Photography
Web: www.hayobaan.nl

Phil Harvey

Yes, Hayo has the best solution.

The problem with your original command is because you are trying to do a for loop as an argument to the join() function, which doesn't work.

- 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

*sigh*  trapped myself in my own brain.

This line of thought was carried over from another command where I was trying to remove an entire HierarchicalSubject entry with regex based upon the last part and couldn't do it without affecting other entries.  I'll have to post that one later to get some input.

Since I'm looking at the keyword at the end of the hierarchy, I think s/(^|##|\|)Jane($|##)/$1Mary$2/g is going to be the final command.

"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype