[comp.unix.internals] puzzle

housed@infmx.informix.com (Darryl House) (11/27/90)

*OOPS* - I included the wrong file in the last message,
here is the right one. Sorry if this causes any
confusion...

The following is a Bourne shell script that illustrates
what I am trying to do: set a shell variable that
contains the contents of another one that is referred
to by concatenating two others. Sufficiently confusing?
Yeah, I thought so, too.

Note that I don't really want to keep track of how many
iterations there are, that'd be absurdly simple to track.
The application is too complex to describe here, but I
did fix the problem by using a C program rather than
a shell script. I just thought that this was a very
interesting puzzle.

--------------------------------------------------------
#! /bin/sh

# what I want is to be able to set
# the ITERATION variable to be the expanded
# version of $PREFIX$SUFFIX, i.e. the first iteration
# would be the contents of $firsttime, the second
# would be the contents of $secondtime. The following
# code gives me errors, and everything I try either gets
# the same substitution failure or just echoes the name
# of the variable, i.e. ($firsttime and $secondtime).

echo

firsttime="first_time"
secondtime="second_time"

PREFIX_WORDS="first second"
SUFFIX="time"

for PREFIX in $PREFIX_WORDS
do

# the following line doesn't work, but
# sort of illustrates what I want to do.
# I want this to be ITERATION=$firsttime the first time
# through and ITERATION=$secondtime the second time.

	ITERATION=${$PREFIX$SUFFIX}

    echo 'Iteration is $ITERATION'
done

echo

exit 0
--------------------------------------------------------

Required output:

prompt% program_name

Iteration is first_time
Iteration is second_time

prompt%

Any hints you can offer will be greatly appreciated.

Thank you, and have a nice day!

hahn@nas.nasa.gov (Jonathan Hahn) (11/27/90)

In article <1990Nov27.003659.3521@informix.com> housed@infmx.informix.com (Darryl House) writes:
>The following is a Bourne shell script that illustrates
>what I am trying to do: set a shell variable that
>contains the contents of another one that is referred
>to by concatenating two others. Sufficiently confusing?

The following script creates a string which accomplishes the
assignment to ITERATION, and calls "eval" to evaluate the string.
BTW, the echo needs double quotes so the value of ITERATION will
be printed.

----------------------------------------------------------------------
	firsttime="first_time"
	secondtime="second_time"

	PREFIX_WORDS="first second"
	SUFFIX="time"

	for PREFIX in $PREFIX_WORDS
	do
	    eval 'ITERATION=$'$PREFIX$SUFFIX
	    echo "Iteration is $ITERATION"
	done
----------------------------------------------------------------------

-jonathan hahn
--
hahn@gigantor.nas.nasa.gov				wk: (415) 604-4360
..!ames!amelia!hahn					hm: (408) 736-7014

skdutta@cs.tamu.edu (Saumen K Dutta) (11/27/90)

In article <1990Nov27.003659.3521@informix.com> housed@infmx.informix.com (Darryl House) writes:
->
->The following is a Bourne shell script that illustrates
->what I am trying to do: set a shell variable that
->contains the contents of another one that is referred
->to by concatenating two others. Sufficiently confusing?
->Yeah, I thought so, too.
->
->Note that I don't really want to keep track of how many
->iterations there are, that'd be absurdly simple to track.
->The application is too complex to describe here, but I
->did fix the problem by using a C program rather than
->a shell script. I just thought that this was a very
->interesting puzzle.
->
->--------------------------------------------------------
->#! /bin/sh
->
-># what I want is to be able to set
-># the ITERATION variable to be the expanded
-># version of $PREFIX$SUFFIX, i.e. the first iteration
-># would be the contents of $firsttime, the second
-># would be the contents of $secondtime. The following
-># code gives me errors, and everything I try either gets
-># the same substitution failure or just echoes the name
-># of the variable, i.e. ($firsttime and $secondtime).
->
->echo
->
->firsttime="first_time"
->secondtime="second_time"
->
->PREFIX_WORDS="first second"
->SUFFIX="time"
->
->for PREFIX in $PREFIX_WORDS
->do
->
-># the following line doesn't work, but
-># sort of illustrates what I want to do.
-># I want this to be ITERATION=$firsttime the first time
-># through and ITERATION=$secondtime the second time.
->
->	ITERATION=${$PREFIX$SUFFIX}
->
->    echo 'Iteration is $ITERATION'
->done
->
->echo
->
->exit 0
->--------------------------------------------------------
->
->Required output:
->
->prompt% program_name
->
->Iteration is first_time
->Iteration is second_time
->
->prompt%
->
->Any hints you can offer will be greatly appreciated.
->
->Thank you, and have a nice day!

When you try to read a value as a variable it is a nice idea to
consider the ( otherwise neglected ! ) eval.

Try this as a substitute :

#! /bin/sh
firsttime="first_time"
secondtime="second_time"

PREFIX_WORDS="first second"
SUFFIX="time"

for PREFIX in $PREFIX_WORDS
do

#  IT WORKS !!!!!

	ITERATION=`eval echo $"$PREFIX$SUFFIX"`

    echo Iteration is $ITERATION
done

echo

------------------

Hope this helps


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

marz@cbnewsm.att.com (martin.zam) (11/28/90)

In article <1990Nov27.003659.3521@informix.com>, housed@infmx.informix.com (Darryl House) writes:
> The following is a Bourne shell script that illustrates
> what I am trying to do: set a shell variable that
> contains the contents of another one that is referred
> to by concatenating two others. Sufficiently confusing?
> Yeah, I thought so, too.
> 
> --------------------------------------------------------
> #! /bin/sh
> 
> # what I want is to be able to set
> # the ITERATION variable to be the expanded
> # version of $PREFIX$SUFFIX, i.e. the first iteration
> # would be the contents of $firsttime, the second
> # would be the contents of $secondtime. The following
> # code gives me errors, and everything I try either gets
> # the same substitution failure or just echoes the name
> # of the variable, i.e. ($firsttime and $secondtime).
> 
> echo
> 
> firsttime="first_time"
> secondtime="second_time"
> 
> PREFIX_WORDS="first second"
> SUFFIX="time"
> 
> for PREFIX in $PREFIX_WORDS
> do
> 
> # the following line doesn't work, but
> # sort of illustrates what I want to do.
> # I want this to be ITERATION=$firsttime the first time
> # through and ITERATION=$secondtime the second time.
> 
> 	ITERATION=${$PREFIX$SUFFIX}
> 
>     echo 'Iteration is $ITERATION'
> done
> 
> echo
> 
> exit 0
> --------------------------------------------------------
> 
> Required output:
> 
> prompt% program_name
> 
> Iteration is first_time
> Iteration is second_time
> 
> prompt%
> 
> Any hints you can offer will be greatly appreciated.

Try this...

firsttime="first_time"
secondtime="second_time"

PREFIX_WORDS="first second"
SUFFIX="time"

for PREFIX in ${PREFIX_WORDS}
do
	ITERATION="${PREFIX} ${SUFFIX}"	# These variables need to be
					# expanded individually, and the
					# quotes preserve the space
					# between them.

	echo "Iteration is $ITERATION"	# Your single quotes didn't allow
					# variable expansion to take place.
done

						Hope this helps,
						Martin Zam
						(201)564-2554

rrvvrr@mixcom.UUCP (Bill Suetholz) (11/30/90)

I tried this shell script and it performs as requested...

-----------------------------CUT HERE -------------------------------------
#!/bin/sh
first_time="first_time"
second_time="second_time"

PREFIX="first second"
SUFFIX="time"

for WORDS in $PREFIX
do

	eval ITERATION=\$${WORDS}_${SUFFIX}

    echo "Iteration is $ITERATION"
done

exit 0
----------------------------------------------------------------------------

A few things to note:
   1)  the line with the eval was supposed to have WORDS not PREFIX in it.
   2)  use eval to get shell to evaluate the line twice;
       once for $WORDS and $SUFFIX and once for $first_time or $second_time.


Bill Suetholz (bills@mixcom.UUNET)