Hi
I didn't want to post - but with not much hair left to pull, i had to search for better braincells.
I have a powershell script running commands to exiftools and i am trying to combine some parameters; i can run the following command and it works;
exiftool -tagsfromfile test.jpg "-XMP:all<GPS:all" test.mp4
then i can pass it to a variable - this works as well;
$Par1 = "-XMP:all<GPS:all"
exiftool -tagsfromfile test.jpg $Par1 test.mp4
However if i try to add another level of single quotes i get this;
$Par1 = '"-XMP:all<GPS:all"'
exiftool -tagsfromfile test.jpg $Par1 test.mp4
Error: File not found - "-XMP:all<GPS:all"
My end goal is to combine several parameters into one variable such as;
$Par1 = '"-XMP:all<GPS:all" "-XMP:GPSLatitude<Composite:GPSLatitude"'
I have seen some comments about needing the backtick (`) character, i have tried placing it most places in the variable but either it doesn't change the issue or i haven't found the magic location.
Hope this is simple to answer for someone.
thanks
PS: this is all run in PS v7
The error tells you the problem. It says Error: File not found - "-XMP:all<GPS:all" Exiftool can't see the hyphen, so it's looking for a filename. And it can't see the hyphen due to the double quotes. It's looking for a file called "-XMP:all<GPS:all", quotes included.
Beyond that, I can't really help you. I've banged my head against the absolute stupidly that is powershell for too long.
Thanks StarGeek
it wasn't the error itself but the root cause which, like you, i was trying to determine.
from my understanding, in PS the single quotes should pass the contents within the variable directly to the command; so
exiftool -tagsfromfile test.jpg "-XMP:all<GPS:all" test.mp4
and this;
$Par1 = '"-XMP:all<GPS:all"'
exiftool -tagsfromfile test.jpg $Par1 test.mp4
Should be equivalent, and yet the first executes without issue and the latter throws the error.
I'm not sure i agree with you that exiftool can't see the hyphen because of the double quotes since it sees it in the first command where it is explicitly defined, The problem I think is we don't know exactly how it is getting parsed, which i suspect is the issue. When i was trying to figure this out I saw someone using the start-process command to pass parameters - it would be interesting to see if this would have a different outcome.
Do you know if exiftool can log what the imput command is? this might help see what is happening.
Use the -echo option to see the arguments as ExifTool reads them.
For example (in a MacOS tcsh shell):
> exiftool -echo "this is a test" -echo '"another test"'
this is a test
"another test"
- Phil
PS E:\Temp4> exiftool -echo -tagsfromfile -echo test.jpg -echo "-XMP:all<GPS:all" -echo test.mp4
-tagsfromfile
test.jpg
-XMP:all<GPS:all
test.mp4
PS E:\Temp4> $Par1 = '"-XMP:all<GPS:all"'
PS E:\Temp4> exiftool -echo -tagsfromfile -echo test.jpg -echo $Par1 -echo test.mp4
-tagsfromfile
test.jpg
"-XMP:all<GPS:all"
test.mp4
Well, at least its progress - StarGeek is partly correct - its not seeing the hyphen because of the quotes. So any ideas why the quotes are stripped of the first command and not the second?
To me this looks like a deficiency in the command processor. It seems as if no argument processing is done on interpolated variable values. If this is true, I can't see how you could ever have a single-argument variable which has a space (or other special character) in the name. But I'm not a Windows expert, so maybe there is a way around this.
However, I wouldn't hold my breath. PowerShell has other known deficiencies that are problematic.
- Phil
well i can insert the parameters one by one and that works in PS, not ideal but maybe if i have more time i'll try to figure this out later.
Thanks again for all your help and a fantastic tool!
Your going to love this!
PS D:\temp3>
PS D:\temp3> $Par1 = @'
>> -XMP:all<GPS:all
>> '@
PS D:\temp3> $Par1
-XMP:all<GPS:all
PS D:\temp3> exiftool -tagsfromfile test.jpg $Par1 test.mp4
1 image files updated
PS D:\temp3>
This is called a Here-String (personally i think an AT (@) string would be a better name but i'm sure someone had a good reason for that name)
Good reading for anyone interested (i wasn't - its stupid but it works that way - move on);
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-7.3 (https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-7.3)
https://devblogs.microsoft.com/scripting/maximizing-the-power-of-here-string-in-powershell-for-configuration-data/ (https://devblogs.microsoft.com/scripting/maximizing-the-power-of-here-string-in-powershell-for-configuration-data/)
So just have to remember this for the next time i'm working on a PS script! Now i can sleep better at night.
Next step - design a universal tagging system ...
Ignore that last post -
Can't see a way to edit or delete that last post
The issue still remains - maybe had to much coffee when i was looking at it;
even if you use here-strings and do;
PS D:\temp3> $Par1 = @'
>> "-XMP:all<GPS:all"
>> '@
PS D:\temp3> $Par1
"-XMP:all<GPS:all"
this will still result in the same error as noted above;
oh well...
there are workarounds - maybe someone will find a solution later.
Thanks again.
Not sure if i have answered my original question, i think so, however i have been trying to combine commands in Powershell, ie;
$Make = 'Apple'
$Model = 'iPhone'
$Action1 = '-XMP:Make=' + $Make
$Action2 = '-XMP:Model=' + $Model
This would work;
exiftool $Action1 $Action2 $File
However if i did;
$Action = $Action1 + $Action2
exiftool $Action $File
This would cause an error
The issue seems to be in the way the variable is passed to exiftool and the way it interprets the string.
After much 'maybe this way', the solution is of course rather simple, the combined variable needs to be passed as an array of the individual commands, ie;
$Action = $Action1,$Action2
exiftool $Action $File
This works
So not sure if this will work on my example on the first post but it at least allows for how to combine the commands.
Hope this helps someone else.