[comp.unix.wizards] nested loops

adley@herbie.misemi ( iccad) (08/10/90)

Hi,
We are trying to write a Bourne shell script that includes two 
nested loops as follows

!# /bin/sh
this="one two three"
that="four five six seven"
them="eight nine ten"
all="this that them"
#
for i in $all
do
for j in $`echo $i`
do
echo $i $j
done
done


we want (and expected!) the output:
this one
this two
this three
that four
that five
that six
that seven
them eight
them nine
them ten

The problem lies in the  $`echo $i` statment
the `echo $i` preforms as expected and the result is one of this,
that, or them
the $ infront of this statment however is taken as a literal $
and does not return the value of the variable this or that or them
instead it returns $this or $that or $them.

Does anybody know why this happens or how we can get the results 
that would be expected here (with the exception of doing it in a 
C shell or in a C program).

Thanks.

skdutta@cs.tamu.edu (Saumen K Dutta) (08/10/90)

In <4103@herbie.misemi> article adley@herbie.misemi writes:   
->
->Hi,
->We are trying to write a Bourne shell script that includes two 
->nested loops as follows
->
->!# /bin/sh
->this="one two three"
->that="four five six seven"
->them="eight nine ten"
->all="this that them"
->#
->for i in $all
->do
->for j in $`echo $i`
->do
->echo $i $j
->done
->done
->
->
->we want (and expected!) the output:
->this one
->this two
->this three
->that four
->that five
->that six
->that seven
->them eight
->them nine
->them ten
->
->The problem lies in the  $`echo $i` statment
->the `echo $i` preforms as expected and the result is one of this,
->that, or them
->the $ infront of this statment however is taken as a literal $
->and does not return the value of the variable this or that or them
->instead it returns $this or $that or $them.
->

If you modify the code in the following way it will work. I bet there
must be a simpler way of doing this:

#! /bin/sh

this="one two three"
that="four five six seven"
them="eight nine ten"
all="this that them"
#
for i in $all
do
k='eval echo $`echo $i`'
for j in `eval $k`
do
echo $i $j 
done
done


--
     _                                   ||Internet: skdutta@cssun.tamu.edu  
    (   /_     _ /   --/-/- _            ||Bitnet : skd8107@tamvenus.bitnet 
   __)_/(_____(_/_(_/_(_(__(_/_______    ||Uucp : uunet!cssun.tamu.edu!skdutta
                                 ..      ||Yellnet: (409) 846-8803

merlyn@iwarp.intel.com (Randal Schwartz) (08/10/90)

In article <7318@helios.TAMU.EDU>, skdutta@cs (Saumen K Dutta) writes:
| this="one two three"
| that="four five six seven"
| them="eight nine ten"
| all="this that them"
| #
| for i in $all
| do
| k='eval echo $`echo $i`'
| for j in `eval $k`
| do
| echo $i $j 
| done
| done

Waaaaayyyy too many eval's and echo's.  Try this:

#!/bin/sh
this="one two three"
that="four five six seven"
them="eight nine ten"
all="this that them"
for i in $all
do
	eval 'for j in $'$i'
	do
		echo $i $j
	done'
done

And look, I didn't mention Perl once (oops!).

(But why is this in wizards?  Sigh.)
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/

gilles@pase60.Convergent.Com (Gilles Courcoux) (08/10/90)

In article <4103@herbie.misemi> you wrote:
>The problem lies in the  $`echo $i` statment

Right, double variable expansion like that is resolved through the use
of the eval(1) command as in :
	eval echo '$'$i

When the shell read the command, it expands it into 
	eval echo $them			# the first time !

and then eval(1) do his job : evaluating its arguments, including
variables expansion and then execute the command which is by now :
	echo one two three

The echo(1) command is needed because eval(1) then exec(2)utes its
first argument.

Your script become :

this="one two three"
that="four five six seven"
them="eight nine ten"
all="this that them"
#
for i in $all
do
	for j in `eval echo '$'$i`
	do
	echo $i $j
	done
done

Have a nice day,

Gilles Courcoux                        E-mail: sun!pyramid!ctnews!pase60!gilles
Unisys Network Computing Group         Phone:  (408) 435-7692

chet@cwns1.CWRU.EDU (Chet Ramey) (08/11/90)

In article <4103@herbie.misemi> adley@herbie.misemi ( iccad) writes:

$ !# /bin/sh
$ this="one two three"
$ that="four five six seven"
$ them="eight nine ten"
$ all="this that them"
$ #
$ for i in $all
$ do
$ for j in $`echo $i`
$ do
$ echo $i $j
$ done
$ done

$ The problem lies in the  $`echo $i` statment
$ the `echo $i` preforms as expected and the result is one of this,
$ that, or them
$ the $ infront of this statment however is taken as a literal $
$ and does not return the value of the variable this or that or them
$ instead it returns $this or $that or $them.

Use `eval'.

Chet
-- 
Chet Ramey				``Levi Stubbs' tears run down
Network Services Group			  his face...''
Case Western Reserve University	
chet@ins.CWRU.Edu		

donlash@uncle.uucp (Donald Lashomb) (08/12/90)

In article <4103@herbie.misemi> adley@herbie.misemi ( iccad) writes:
=[...]
=The problem lies in the  $`echo $i` statment
=the `echo $i` preforms as expected and the result is one of this,
=that, or them
=the $ infront of this statment however is taken as a literal $
=and does not return the value of the variable this or that or them
=instead it returns $this or $that or $them.
=[...]

Try using an eval like this:  eval $`echo $i`
eval causes the shell to "double-scan" the line,
thereby picking up and evaluating the ${this/that/whatever}
as a variable.

-Don

merlyn@iwarp.intel.com (Randal Schwartz) (08/14/90)

In article <1990Aug12.030137.19989@uncle.uucp>, donlash@uncle (Donald Lashomb) writes:
| Try using an eval like this:  eval $`echo $i`
| eval causes the shell to "double-scan" the line,
| thereby picking up and evaluating the ${this/that/whatever}
| as a variable.

Please don't use `echo $i`, as it is equivalent to $i for all plain
values of $i, and forks an extra process or two on BourneShellClassic.
As I said in an earlier post, eval echo \$$i does pretty much what you
wanted in this case.

Just another Bourne Shell hacker,
-- 
/=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\
| on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III      |
| merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn |
\=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/