LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Newbie (https://www.linuxquestions.org/questions/linux-newbie-8/)
-   -   Another problem script -- "unexpected token" error (https://www.linuxquestions.org/questions/linux-newbie-8/another-problem-script-unexpected-token-error-914354/)

SilversleevesX 11-19-2011 01:28 AM

Another problem script -- "unexpected token" error
 
I have run bash -x and -v debug lines on this one, but it still offers up no clue.

In fact, bash -x (nameofscript) returns only the echos to introduce the script, runs them, then at the first 'if' test, stops and repeats the error.

Here's the code:
Code:

#!/bin/bash
SAVEIFS=$IFS
IFS=$'\n\b'
x=1
y=0

echo "XMP Label to IPTC tag Copier"
echo "Copies found XMP Labels to their"
echo "corresponding IPTC tags using Exiv2."
echo "(And now it will read and copy from '.exv' files)"
echo "Requires ImageInfo a/w/a Exiv2"
echo
if [ -f "xmp-evaluated.txt" ]; then
        mv "xmp-evaluated.txt" "xmp-evaluated-old.txt"
fi

function gettext () {
        echo -e "What list will I be using?"
        read thelist
}
#Getting the date for the log
function logdate () {
        mydate=$(echo $(date "+%A, %B %d %Y at %I:%M %p %Z."))
}
function keyswrite () {
        SAVEIFS=$IFS; IFS=$(echo -en "\n\b")
        w=1
        for riall;do exiv2 -kM"add Iptc.Application2.Keywords String $riall" $file ;((w++)); done
        IFS=$SAVEIFS
}
function catswrite () {
        SAVEIFS=$IFS; IFS=$(echo -en "\n\b")
        x=1
        for monk; do exiv2 -kM"add Iptc.Application2.SuppCategory String $monk" $file ; ((x++)) ; done
        IFS=$SAVEIFS
}
function ricoh() {
        echo "Copying."
        echo -ne "Writing: "
        if [ "$icat" != "" ]; then
                exiv2 -kM"set Iptc.Application2.Category $icat" $file
                echo -ne "CATEGORY\t"
        fi
        if [ "$icrd" != "" ]; then
                exiv2 -kM"set Iptc.Application2.Credit $icrd" $file
                echo -ne "CREDIT  "
        fi
        if [ "$isrc" != "" ]; then
                exiv2 -kM"set Iptc.Application2.Source $isrc" $file
                echo -ne "SOURCE  "
        fi
        if [ "$iwrit" != "" ]; then
                exiv2 -kM"set Iptc.Application2.Writer $iwrit" $file
                echo -ne "WRITER\n"
        fi
        if [ "$itran" != "" ]; then
                exiv2 -kM"set Iptc.Application2.TransmissionReference $itran" $file
                echo -ne "TRANSMISSION REFERENCE  "
        fi
        if [ "$fixid" != "" ]; then
                exiv2 -kM"set Iptc.Application2.FixtureId $fixid" $file
                echo -ne "FIXTURE IDENTIFIER  "
        fi
        echo
        if [ "$objnm" != "" ]; then
                exiv2 -kM"set Iptc.Application2.ObjectName $objnm" $file
                echo -ne "OBJECT NAME  "
        fi
        if [ "$iloc" != "" ]; then
                exiv2 -kM"set Iptc.Application2.SubLocation $iloc" $file
                echo -ne "SUBLOCATION  "
        fi
        if [ -n "$capn" ]; then
                exiv2 -kM"set Iptc.Application2.Caption String $capn" $file
                echo -ne "Writing: CAPTION  "
        fi
        if [ -n "$pkey" ]; then
                echo -ne "KEYWORDS  "
                keyswrite
        fi
        if [ -n "$pcat" ]; then
                echo -ne "SUPPLEMENTAL CATEGORIES  "
                catswrite
        fi
        if [ -n "$spinstr" ]; then
                exiv2 -kM"set "Xmp.photoshop.SpecialInstructions XmpText $xspn" $file
                echo -ne "SPECIAL INSTRUCTIONS\n"
        fi
        echo -ne "\n"
}


gettext
echo "Creating evaluation file."
sleep 3
logdate
echo "Writing log date to file..."
echo -e "This XMP meta-evaluation was started on $mydate\n">>xmp-evaluated.txt
echo -ne "LIST NAME:\t$thelist\n">>xmp-evaluated.txt
echo -e "File dated, source list recorded.\n"
nimnum=$(cat $thelist | wc -l)
echo -e "-- $nimnum items --\n">>xmp-evaluated.txt
echo -ne "There are $nimnum files to be evaluated.\n\n"

while read line
do
file=$line
q=$(basename "$file")
echo -ne "Evaluating File #$x \ $q.\n\n"
if [[ ! "$line" =~ ".exv" ]]; then
        thrice=$(imageinfo --geom $file)
else
        thrice="N/A - hex data"
fi

echo -e "File $x is: $line ($thrice)">>xmp-evaluated.txt
        cate=$(exiv2 -g Xmp.photoshop.Category -Pv $file)
        if [[ "$cate" != "" ]]; then
                cate2="Category Tag"
                icat=$cate
                echo "Category:$cate">>xmp-evaluated.txt
        fi
        cred=$(exiv2 -g Xmp.photoshop.Credit -Pv $file)
        if [[ "$cred" != "" ]]; then
                cred2="Credit Tag"
                icrd=$cred
                echo "Credit:$cred">>xmp-evaluated.txt
        fi
        sour=$(exiv2 -g Xmp.photoshop.Source -Pv $file)
        if [[ "$sour" != "" ]]; then
                sour2="Source Tag"
                isrc=$sour
                echo "Source:$sour">>xmp-evaluated.txt
        fi
        writ=$(exiv2 -g Xmp.photoshop.CaptionWriter -Pv $file)
        if [[ "$writ" != "" ]]; then
                writ2="Writer Tag"
                iwrit=$writ
                echo "Writer:$writ">>xmp-evaluated.txt
        fi
        trans=$(exiv2 -g Xmp.photoshop.TransmissionReference -Pv $file)
        if [[ "$trans" != "" ]]; then
                trans2="Transmission Reference Tag"
                itran=$trans
                echo "Transmission Reference:$trans">>xmp-evaluated.txt
        fi
        event=$(exiv2 -g Xmp.expressionmedia.Event -Pv $file)
        if [[ "$event" != "" ]]; then
                event2="Event Tag"
                fixid=$event
                echo "Event:$event">>xmp-evaluated.txt
        fi
        title0=$(exiv2 -g Xmp.dc.title -Pv $file)
        title=${title0#* }
        if [[ "$title" != "" ]]; then
                title2="Title Tag"
                objnm=$title
                echo "Title:$objnm">>xmp-evaluated.txt
        fi
        locn=$(exiv2 -g Xmp.iptc.Location -Pv $file)
        if [[ "$locn" != "" ]]; then
                locn2="Location Tag"
                iloc=$locn
                echo "Location:$locn">>xmp-evaluated.txt
        fi
        desc=$(exiv2 -g Xmp.dc.description -Pv $file)
        if [ -n "$desc" ]; then
                desc2="Caption"
                capn=$desc
                echo "Has Caption">>evaluated.txt
        fi
        subj=$(exiv2 -g Xmp.dc.subject -Pv $file)
        if  [ -n "$keys" ]; then
                keys2="Keywords"
                keys=$subj
                echo "Has Keywords.">>xmp-evaluated.txt
        fi
        pcat=$(exiv2 -g Xmp.photoshop.SupplementalCategories -Pv $file)
        if  [ -n "$pcat" ]; then
                cats2="Supplemental Categories"
                cats=$pcat
                echo "Has Supplemental Categories.">>-xmp-evaluated.txt
        fi
        xspn=$(exiv2 -g Xmp.photoshop.SpecialInstructions -Pv $file)
        if [[ "$xspn" != "" ]]; then
                spin2="Sublocation Tag"
                spinstr=$xspn
                echo "Has Special Instructions">>xmp-evaluated.txt
        fi
iptc=$(echo -e "$cate2 $cred2 $sour2 $writ2 $trans2 $event2 $title2 $locn2 $desc2 $keys2 $cats2 $spin2" )
if [ "X${iptc}" != "X" ]; then
        ricoh
else
        echo -ne "I see no values in any XMP meta tag in file $q.\nNothing to copy."
fi
echo -ne "\n" >>xmp-evaluated.txt
(( x++ ))
done<$thelist

I think it might be, as my last errant script was, a matter of my not seeing a missing 'fi' to an 'if,' closed bracket or parenthesis, or something simple like that. I have an almost-identical script that performs the opposite task (copying IPTC to XMP), and that still runs with no errors. Maybe something got "lost in the translation?"

Just so folks know ahead of time, the two lines
Code:

title0=$(exiv2 -g Xmp.dc.title -Pv $file)
        title=${title0#* }

in the vicinity of lines 153-54 are necessary as Exiv2 includes its identification of the intended language for that tag (XMP DC Core Title) in the return for that "exvi2 -g...-Pv" command. I was going to suggest to Andreas Huggel, Exiv2's author and maintainer, that it's as well to leave it out, but as soon as I thought of it, I found myself installing the next version in two builds and forgot all about it. :|

I look forward to suggestions. In the meantime, I have other means by which to achieve the tasks this script does.

BZT

grail 11-19-2011 03:21 AM

Wrong number quotes:
Code:

if [ -n "$spinstr" ]; then
    exiv2 -kM"set "Xmp.photoshop.SpecialInstructions XmpText $xspn" $file
    echo -ne "SPECIAL INSTRUCTIONS\n"
fi

You probably could reduce the number of if's by looking at how much you are repeating in each.

SilversleevesX 11-21-2011 12:02 AM

Thanks again grail
 
I appreciate your suggestion about the number of ifs, and it calls to mind one thought I had when writing the script this was derived from. I really wanted it to be able to log what Exiv2 found and copy the tag value to the corresponding field simultaneously or, barring that, in so quick succession as to make no difference. Looked at another way, if the copying was done within the same loop as the logging, that would definitely reduce the number of if/fi tests, at first glance by half. It will certainly take some work, but I also certainly see the sense in rewriting the script with that (dropping the number of if tests, particularly since so many of them repeat themselves) as a goal.

Bye-bye "ricoh" function. *G*

Thanks again.

BZT

grail 11-21-2011 02:21 AM

I agree with other comments I have seen on your posts though ... how do you go about having data delimited by a newline and a backspace? (very curious)

grail 11-21-2011 07:15 PM

Also something like the following format may help reduce what you have:
Code:

declare -a photoshop_arr

photoshop_arr=(        Category                \
                Credit                        \
                Source                        \
                CaptionWriter                \
                TransmissionReference        \
                SupplementalCategories        \
                SpecialInstructions        )

        for counter in ${!photoshop_arr[*]}
        do
                result=$(exiv2 -g Xmp.photoshop.${photoshop_arr[counter]} -Pv $line)
                if [[ $result ]]
                then
                        exiv2 -kM"set Iptc.Application2.${photoshop_arr[counter]} $result" $line
                        echo "${photoshop_arr[counter]}:$result">>xmp-evaluated.txt
                fi
        done

Not the only solution but thought it would give you something to think about :)

Also the use of global variables and constant setting and changing to new variables seems a bit over the top,
eg:
Code:

cate=$(exiv2 -g Xmp.photoshop.Category -Pv $file)
        if [[ "$cate" != "" ]]; then
                cate2="Category Tag"
                icat=$cate

Here the examples are cate and icat and then why not just pass variables as parameters to your functions??

Something else that confuses me is:
Code:

for riall;do exiv2 -kM"add Iptc.Application2.Keywords String $riall" $file ;((w++)); done
Here you are saying 'riall' is each item in a list of parameters (usually referenced as $@) passed to your function and yet the call to the function is:
Code:

if [ -n "$pkey" ]; then
    echo -ne "KEYWORDS  "
    keyswrite
fi

As it stands this would appear that neither for loop in this format would ever run?

SilversleevesX 11-22-2011 02:07 AM

Trying a little "reduction"
 
I went back to the script this one was derived from, and tried to eliminate the redundant if/then/fi's and unnecessary variable value passing. I think, at one point, what I had in mind for both scripts was a "pause" to let the user decide whether or not they actually wanted to copy what data was found to the file in the other metadata block (area? zone?). But that would have meant another 'read,' and as there was already a 'while read' loop running, the first one was sure to 'run over' the second one, so I didn't pursue it.

The 'for' loops for adding Keywords and Supplemental Categories were still glitchy (and now I see why). In this script they've been removed altogether.

I'm including the "trimmed" code of the other script here for comments and suggestions.
Code:

echo "Copying..."

echo -e "File is: $line (${thrice#*:})">>evaluated.txt
        cate=$(exiv2 -g Iptc.Application2.Category -Pv $file)
        if [[ -n "$cate"  ]]; then
                cate2="Category Tag"
                cate=$cate
                echo "Category:$cate">>evaluated.txt
                exiv2 -kM"set Xmp.photoshop.Category XmpText $cate" $file
                echo -ne "CATEGORY  "
        fi
        cred=$(exiv2 -g Iptc.Application2.Credit -Pv $file)
        if [[ -n "$cred"  ]]; then
                cred2="Credit Tag"
                cred=$cred
                echo "Credit:$cred">>evaluated.txt
                exiv2 -kM"set Xmp.photoshop.Credit XmpText $cred" $file
                echo -ne "CREDIT  "
        fi
        sour=$(exiv2 -g Iptc.Application2.Source -Pv $file)
        if [[ -n "$sour"  ]]; then
                sour2="Source Tag"
                echo "Source:$sour">>evaluated.txt
                exiv2 -kM"set Xmp.photoshop.Source XmpText $sour" $file
                echo -ne "SOURCE  "
        fi
        writ=$(exiv2 -g Iptc.Application2.Writer -Pv $file)
        if [[ -n "$writ"  ]]; then
                writ2="Writer Tag"
                echo "Writer:$writ">>evaluated.txt
                exiv2 -kM"set Xmp.photoshop.CaptionWriter XmpText $writ" $file
                echo -ne "WRITER  "
        fi
        trans=$(exiv2 -g Iptc.Application2.TransmissionReference -Pv $file)
        if [[ -n "$trans"  ]]; then
                trans2="Transmission Reference Tag"
                echo "Transmission Reference:$trans">>evaluated.txt
                exiv2 -kM"set Xmp.photoshop.TransmissionReference XmpText $trans" $file
                echo -ne "TRANSMISSION REFERENCE  "
        fi
        fixid=$(exiv2 -g Iptc.Application2.FixtureId -Pv $file)
        if [[ -n "$fixid"  ]]; then
                fixid2="Fixture Identifier Tag"
                echo "Fixture Identifier:$fixid">>evaluated.txt
                exiv2 -kM"set Xmp.expressionmedia.fixid XmpText $fixid" $file
                echo -ne "EVENT  "
        fi
        objnm=$(exiv2 -g Iptc.Application2.ObjectName -Pv $file)
        if [[ -n "$objnm"  ]]; then
                objnm2="Object Name Tag"
                echo "Object Name:$objnm">>evaluated.txt
                exiv2 -kM"set Xmp.dc.objnm LangAlt $objnm" $file
                echo -ne "TITLE  "
        fi
        locn=$(exiv2 -g Iptc.Application2.SubLocation -Pv $file)
        if [[ -n "$locn"  ]]; then
                locn2="Sublocation Tag"
                echo "Sub-location:$locn">>evaluated.txt
                exiv2 -kM"set Xmp.iptc.Location $locn" $file
                echo -ne "LOCATION  \n"
        fi
        desc=$(exiv2 -g Iptc.Application2.Caption -Pv $file)
        if [ -n "$desc" ]; then
                desc2="Caption"
                echo "Has Caption">>evaluated.txt
                exiv2 -kM"set Xmp.dc.description LangAlt $desc" $file
                echo -ne "CAPTION  "
        fi
        spinstr=$(exiv2 -g Iptc.Application2.SpecialInstructions -Pv $file)
        if [[ -n "$spinstr"  ]]; then
                spin2="Special Instructions Tag"
                echo "Has Special Instructions">>evaluated.txt
                exiv2 -kM"set Xmp.photoshop.SpecialInstructions XmpText $spinstr" $file
                echo -ne "SPECIAL INSTRUCTIONS\n"
        fi
        docid=$(exiv2 -g Exif.Image.DocumentName -Pv $file)
        if [ -n "$docid" ]; then
                achtung="Also found an \033[4;1;32mEXIF Document ID\033[0m tag with data. Writing that to XMP now."
                echo -e "\n$achtung\n(This will not be noted in the evaluation file.)\n"
                exiv2 -kM"set Xmp.xmpMM.DocumentID XmpText $docid" $file

I think, for instance, there are too many double brackets for the 'has a length/doesn't have a length' tests.

I appreciate all the help and suggestions, and if I should run into a problem with making the script in my OP less redundant, I'll be sure to try a few of them.

Good times, all.

BZT

SilversleevesX 11-24-2011 11:17 AM

Quote:

Originally Posted by grail (Post 4530234)
Something else that confuses me is:
Code:

for riall;do exiv2 -kM"add Iptc.Application2.Keywords String $riall" $file ;((w++)); done
Here you are saying 'riall' is each item in a list of parameters (usually referenced as $@) passed to your function and yet the call to the function is:
Code:

if [ -n "$pkey" ]; then
    echo -ne "KEYWORDS  "
    keyswrite
fi

As it stands this would appear that neither for loop in this format would ever run?

I took a look at those functions this morning. I also looked at the scripts from which I borrowed much of the code for them. It turns out I wasn't "setting" the value returned in the command "exiv2 -g Xmp.dc.subject -Pv $file", just as one example, at all. The customized IFS and for loop were, indeed, working on empty values and therefore the functions could not execute, as you observed.

I think these edited ones should work, however.
Code:

#for XMP to IPTC
function keyswrite () {
        SAVEIFS=$IFS; IFS=$','
        set keys
        w=1
        for riall;do exiv2 -kM"add Iptc.Application2.Keywords String $riall" $file ;((w++)); done
        IFS=$SAVEIFS
}
function catswrite () {
        SAVEIFS=$IFS; IFS=$','
        set cats
        x=1
        for monk; do exiv2 -kM"add Iptc.Application2.SuppCategory String $monk" $file ; ((x++)) ; done
        IFS=$SAVEIFS
}

#for IPTC to XMP
function keyswrite () {
        SAVEIFS=$IFS; IFS=$'\n'
        set keys
        w=1
        for riall;do exiv2 -kM"set Xmp.dc.subject XmpBag $riall" $file ;((w++)); done
        IFS=$SAVEIFS
}
function catswrite () {
        SAVEIFS=$IFS; IFS=$'\n'
        set cats
        x=1
        for monk; do exiv2 -kM"set Xmp.photoshop.SupplementalCategories XmpBag $monk" $file ; ((x++)) ; done
        IFS=$SAVEIFS
}

I wrote them back into their respective scripts, but didn't invoke them with any other line in either one. I wanted to get a few comments first, rather than risk running into an error or missing the chance of finding out there's a faster, simpler, more efficient way of doing the same thing in BASH (or Perl, AWK, elsewhere).

I'm also looking at the array suggestion as a way to speed up an older script that checks 7 or 8 IPTC fields and writes the names of the ones without any string length to a text file. With this I might be running before I dare walk. But finding a means of slimming down that other script has been a goal of mine for a couple of years now.

But back to the topic of these scripts. As they are written now, have I made the changes necessary to get the above functions to work, and not just look like they're doing so with the "friendly but meaningless" echos to stdout ?

BZT

grail 11-24-2011 05:23 PM

Well I am not sure as I do not know where 'keys' or 'cats' is coming from?

SilversleevesX 11-27-2011 10:35 PM

You're in good company, grail. For now, anyway. *S*
 
Quote:

Originally Posted by grail (Post 4533137)
Well I am not sure as I do not know where 'keys' or 'cats' is coming from?

Good point. I just took a look at one of the scripts, and it appears that any command to read either IPTC keywords or XMP subject (the property names respectively in both 'blocks') is missing. Whether I took it out deliberately out of frustration over an error is irrelevant, as a script without a command to assign some value to a variable would inevitably throw errors at the point where it was asked to write that value out to a file, singly or as an array sequence. And I do have the "catswrite" function back as un-commented lines.

In other words, and without the extraneous commentary, if you don't know where 'keys' and 'cats' are coming from, you're not alone. At this point, neither do the subshells executing the commands in the scripts.

BZT


All times are GMT -5. The time now is 06:39 PM.