BashScripts.org
http://bashscripts.org/forum/

Problem with nested loops
http://bashscripts.org/forum/viewtopic.php?f=16&t=588
Page 1 of 1

Author:  riayi [ Tue Nov 04, 2008 6:18 pm ]
Post subject:  Problem with nested loops

Hello:

I wasn't sure if this was better off here or in the basics forum, seeing as it is one of my first scripts, but I was afraid someone would say it didn't belong in that forum. To make a long story short, I have a series of text files that contain commercial medicine names along with the amount used by month, and these I need to make into generic names. After mucking about some, I made a script to pair the name with a generic name and substitute it, using awk and sed, and all was well. Later, I tried to remove the absolute paths to the involved files from the script (so I could use the same script for files in different directories), and it stopped working, and hasn't worked even after I replaced the paths. The shell returns the following error:
Quote:
./gen.sh: line 33: syntax error near unexpected token `done'
./gen.sh: line 33: `done'
. The script is as follows:
Code:
#!/bin/bash
#script to change from commercial to generic names
outer=1
num=107
total=`wc -w lista.txt | awk '{ print $1 }'`
while [ $outer -lt 10 ]
do
        inner=1
        while [ $inner -lt $((total)) ]
        do
                brand=`cat lista.txt | awk '{ print $'$inner' }'`
                gen=`cat lista.txt | awk '{ print $'$((inner+1))' }'`
                sed -i --line-length=0 s/$brand/$gen/g /home/yon/Residencia/tesis/2007/rfaran10_int_0$num.txt
                inner=$((inner+2))
        done
        outer=$((outer+1))
        num=$((num+100))
done
num=1007
total=`wc -w lista.txt | awk '{ print $1 }'`
while [ $outer -lt 13 ];
do
        inner=1
        while [ $inner -lt $((total)) ]
        do
                brand=`cat lista.txt | awk '{ print $'$inner' }'`
                gen=`cat lista.txt | awk '{ print $'$((inner+1))' }'`
                sed -i --line-length=0 s/$brand/$gen/g /home/yon/Residencia/tesis/2007/rfaran10_int_$num.txt
                inner=$((inner+2))
        done
        outer=$((outer+1))
        num=$((num+100))
done

Could anyone help me figure out what is wrong? The do's and done's seem paired alright, and I can't see what I'm missing

Yonatan

Author:  foster [ Sat Nov 08, 2008 10:02 am ]
Post subject:  Problem with loops!!

I have taken a look at the script you have written, and what you need to run is "bash -x ./gen.sh", this will help you view where the problem is located. The bash -x line shows the output to every line executed.

Author:  riayi [ Sun Nov 09, 2008 11:50 am ]
Post subject:  Tracing with -x

I ran the script as suggested, and the output provides me with too little information, I think...
Quote:
+ outer=$'1\r'
+ num=$'107\r'
++ wc -w lista.txt
++ awk '{ print $1 }'
+ total=$'234\r'
./gen.sh: line 33: syntax error near unexpected token `done'
./gen.sh: line 33: `done'


Any other pointers, please?

Author:  jeo [ Mon Nov 10, 2008 12:14 pm ]
Post subject: 

Hmm... I'm not 100% sure this is the problem without testing it, but you've got a slight difference in syntax at the start of your while loops:

Code:
while [ $outer -lt 10 ]
do

=====

while [ $outer -lt 13 ];
do


you use a semicolon on one, but not the other. Try writing those lines this way:

Code:
while [ $outer -lt 10 ]; do


Let us know how it goes!

-J

Author:  foster [ Wed Nov 12, 2008 7:30 am ]
Post subject:  Problem with loops!!

It looks like from the output that the problem is with the second loop (inner). It fails before reaching that loop the following line shows at what point the script fails.

+ total=$'234\r' <----------- This is the value before reaching the next while loop (while [$outer -lt 13]) but fails on the next line.
./gen.sh: line 33: syntax error near unexpected token `done'
./gen.sh: line 33: `done'


I think the last post had it backwards and you should remove the semicolon from the inner loop as follows:


old:

while [ $outer -lt 13 ];
do


new
while [ $outer -lt 13 ]
do

Author:  jeo [ Wed Nov 12, 2008 10:59 am ]
Post subject: 

I think Foster's got it, but a note on semicolons: If your "while" and "do" are on the same line, they should be separated with semicolons. I usually do them on the same line, but that's just a style thing. If "do" is on the next line, like you have it, there should be no semicolons. I don't think bash cares if you end a line with a semicolon though (it might depend on the version...), so it should work fine either way, I was just pointing out the inconsistency :)

I'm still not sure what's going on there, even with the bash -x output. As foster pointed out, the last thing it does before the syntax error is set the "total" variable, so it's not even completing any of your loops, or we would at least see the next step: "+ '[' 1 -lt 234 ']'"

The code itself executes fine for me, so I'm wondering if it has to do with the input data. You're not quoting any of your variables, so if there are any special characters in your sample data, it could throw a wrench in the works. I don't think we're even getting to the point where we're workign with the data though if we're not even processing a loop...

-J

Author:  riayi [ Thu Nov 13, 2008 3:55 pm ]
Post subject: 

Thanks for all the replies. I removed the semicolon, and as jeo said, it made no difference. The answer then probably _is_ the data itself... the lista.txt file is a list of generic and brand names, one after the other, so first a brand name is read into $brand and its generic name into $gen, for every pair of names... it's a continuous line without any line breaks that reads (for example):
Quote:
KEFLEX cefalexine AUGMENTIN amoxicilline-clavulanate
. I'll check the file, as I don't remember modifying it and it used to work...

Page 1 of 1 All times are UTC - 6 hours
© 2000, 2002, 2005, 2007 phpBB Group • http://www.phpbb.com