LinuxQuestions.org
Latest LQ Deal: Linux Power User Bundle
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-19-2011, 02:28 AM   #1
SilversleevesX
Member
 
Registered: May 2009
Posts: 181
Blog Entries: 9

Rep: Reputation: 15
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
 
Old 11-19-2011, 04:21 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,552

Rep: Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898
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.
 
1 members found this post helpful.
Old 11-21-2011, 01:02 AM   #3
SilversleevesX
Member
 
Registered: May 2009
Posts: 181
Blog Entries: 9

Original Poster
Rep: Reputation: 15
Smile 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
 
Old 11-21-2011, 03:21 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,552

Rep: Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898
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)
 
1 members found this post helpful.
Old 11-21-2011, 08:15 PM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,552

Rep: Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898
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?
 
1 members found this post helpful.
Old 11-22-2011, 03:07 AM   #6
SilversleevesX
Member
 
Registered: May 2009
Posts: 181
Blog Entries: 9

Original Poster
Rep: Reputation: 15
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

Last edited by SilversleevesX; 11-22-2011 at 03:16 AM. Reason: Double word; added cogent detail.
 
Old 11-24-2011, 12:17 PM   #7
SilversleevesX
Member
 
Registered: May 2009
Posts: 181
Blog Entries: 9

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by grail View Post
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

Last edited by SilversleevesX; 11-24-2011 at 12:23 PM. Reason: Extra right-hand parenthesis made it look funny.
 
Old 11-24-2011, 06:23 PM   #8
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,552

Rep: Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898Reputation: 2898
Well I am not sure as I do not know where 'keys' or 'cats' is coming from?
 
Old 11-27-2011, 11:35 PM   #9
SilversleevesX
Member
 
Registered: May 2009
Posts: 181
Blog Entries: 9

Original Poster
Rep: Reputation: 15
You're in good company, grail. For now, anyway. *S*

Quote:
Originally Posted by grail View Post
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

Last edited by SilversleevesX; 11-27-2011 at 11:46 PM. Reason: Cropped a redundant phrase.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Could anyone help me for this "syntax error near unexpected token done" problem shellone Programming 6 07-24-2011 12:44 AM
[SOLVED] Script error: "syntax error near unexpected token 'then'" RyuuzakiMasato7 Linux - Server 18 06-20-2011 10:28 AM
syntax error unexpected token near "then" pclimmex Linux - Newbie 1 06-20-2008 11:51 PM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 06:57 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration