LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   BASH Script, command line, same commands, different returns (need help). (https://www.linuxquestions.org/questions/linux-newbie-8/bash-script-command-line-same-commands-different-returns-need-help-786992/)

SilversleevesX 02-04-2010 10:17 AM

BASH Script, command line, same commands, different returns (need help).
 
I'm trying to write a bash script to process jpeg files and replace one IPTC4 tag, "Fixture Identifier," that I know all of them have in them, using Andreas Huggel's exiv2 command-line utility.

I confess to using the IPTC fields my own unique way, and I have been using "Fixture Identifier" (aka "Event" in MS Expression Media) as a 'refinement' on "Transmission Reference," to which for years I've been applying short, often catchy descriptive two- and three-word phrases to describe the content of the pictures.

Okay, enough background. Here's the code for the script so far. What I decided to do first was have the user type in the full filename, with extension when applicable, and have exiv2 return the Fixture ID tag as it was presently written in the file. I've been, for at least three and a half hours, using the same jpeg file as a test file. I happen to know that the value of 'FixtureID' in this file is "Bust-ing Out." What Im puzzled by is how nearly identical code can give back such un-identical information.

Pasted into rxvt, this code works:

Code:

exiv2 -PInv bv1329-014.jpg | grep 'FixtureId' | sed 's/^FixtureId[      ]*//'
Which means it answers back with both words in the FixtureID tag "Busting" and "Out" (no quotes oc).

In the script I'm writing, the same code looks like this (employing a variable to be echo'd later)

Code:

oldf1=(`exiv2 -PInv $gfile | grep 'FixtureId' | sed 's/^FixtureId[      ]*//'`)
When the script is run, I only see "Busting" (nq).

What's missing? Or is there a better way to go about it?

BZT

catkin 02-04-2010 10:34 AM

Quote:

Originally Posted by SilversleevesX (Post 3852516)
Code:

oldf1=(`exiv2 -PInv $gfile | grep 'FixtureId' | sed 's/^FixtureId[      ]*//'`)

The ( ) tells bash to start a subshell, to run the given commands and to write the output to stdout (the ` ` does not change anything) and then to assign the expression to $oldf1. Problem is, bash parses the expression so the effect is
Code:

oldf1=Busting Out
which makes bash assign Busting to $oldf1 and then run an Out command with that variable assignment in effect. Probably there is no Out command in the directories defined by $PATH so it should (TM) produce an error message.

You can achieve what you want with
Code:

oldf1=$(exiv2 -PInv $gfile | grep 'FixtureId' | sed 's/^FixtureId[      ]*//')
I have replaced ` ` with $( ) because it is preferred, for the reasons explained here.

SilversleevesX 02-04-2010 11:02 AM

Many thanks catkin.
 
I honestly wasn't expecting such a quick reply. I'll try the better syntax in a few minutes; no doubt it will improve things drastically.

And here, after making my alpha post to this thread, I went Google-ing to see if anyone else had suggestions. I would have been better off to stick around these parts.

I have to agree with GreyCat. To my way of thinking, we all routinely use the other punctuation mark (the tilde) on the same key as the backtick, and that is more than enough. One shouldn't strain one's pinky if there's a better way to do something. :cool:

Provided this change works (and there's no reason at all to think it shouldn't), I can get on with the part of the script I was more confident about to begin with: having exiv2 trash the old FixtureId value for a new one read in from user input. Of course, I'll write in an "Are you sure you want to make this change?" as a good, working 'bail out' option, but on the whole, I don't think it will see much use.

Thanks again.

BZT

David the H. 02-04-2010 11:47 AM

By the way, there's no need to use both grep and sed here, as sed has equivalent line-matching ability. Though you do have to invert it with -n and the 'p' command so that it prints only the lines that match.
Code:

oldf1=$(exiv2 -PInv $gfile | sed -n '/FixtureId/ s/^FixtureId[      ]*//p')
And really, you don't even really need the address field with the above at all, since the "s///" part will match anyway. But it does make sed a tad more efficient when it doesn't have to attempt substitutions on every line.

allanf 02-04-2010 03:46 PM

The "$( ....)" in the assignment probably best done as:
Code:

variable="$(......)"
Because if it returns more than on white spaced tokens you want all of them. If you want to reference the those tokens in a random fashion, then
use
Code:

variable=( $(.....) )
Which is a array assignment. ${#variable} returns the number of items in the array. ${variable[0]} returns the first item in the array and ${variable[*]} returns all the values as a string.


All times are GMT -5. The time now is 11:29 PM.