f



Variable variable name

Sorry for the cryptic subject, but I am trying to do the following (line 
numbers first) in a shell script:

15 type=AD
16 file=100000_10000_AD.csv
17 eval $type_10K=( `cat $file` )

I get the following error message:
+ type=AD
+ file=100000_10000_AD.csv
combinetab.sh: line 17: syntax error near unexpected token `('
combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'

Isn't eval supposed to replace $type with AD and then put the contents 
of $file in an array names AD_10K?

Thanks for any comments.
-Samik
0
Samik
9/12/2006 4:24:45 PM
comp.unix.shell 15484 articles. 3 followers. Post Follow

12 Replies
1299 Views

Similar Articles

[PageSpeed] 8

Samik R. wrote:
> Sorry for the cryptic subject, but I am trying to do the following (line
> numbers first) in a shell script:
>
> 15 type=AD
> 16 file=100000_10000_AD.csv
> 17 eval $type_10K=( `cat $file` )
>
> I get the following error message:
> + type=AD
> + file=100000_10000_AD.csv
> combinetab.sh: line 17: syntax error near unexpected token `('
> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>
> Isn't eval supposed to replace $type with AD and then put the contents
> of $file in an array names AD_10K?

you may want to escape some special characters, like the '$', and the
backtick, and also use parens with ${type}, otherwise it might be
treated as ${type_10K}.  and more, do not forget to use quotation marks
whenever they are needed..

    eval "${type}_10K=\" \`cat \$file\` \""
or
    eval "${type}_10K=\" \$(cat \$file) \""

Good luck,
Xicheng

0
Xicheng
9/12/2006 4:50:49 PM
Xicheng Jia wrote:
> Samik R. wrote:
>> Sorry for the cryptic subject, but I am trying to do the following (line
>> numbers first) in a shell script:
>>
>> 15 type=AD
>> 16 file=100000_10000_AD.csv
>> 17 eval $type_10K=( `cat $file` )
>>
>> I get the following error message:
>> + type=AD
>> + file=100000_10000_AD.csv
>> combinetab.sh: line 17: syntax error near unexpected token `('
>> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>>
>> Isn't eval supposed to replace $type with AD and then put the contents
>> of $file in an array names AD_10K?
> 
> you may want to escape some special characters, like the '$', and the
> backtick, and also use parens with ${type}, otherwise it might be
> treated as ${type_10K}.  and more, do not forget to use quotation marks
> whenever they are needed..
> 
>     eval "${type}_10K=\" \`cat \$file\` \""
> or
>     eval "${type}_10K=\" \$(cat \$file) \""
> 
> Good luck,
> Xicheng
> 
Thanks Xicheng. The following worked:
eval "${type}_10K=( \`cat $file\` )"
0
Samik
9/12/2006 5:30:32 PM
On 2006-09-12, Samik R. wrote:
> Sorry for the cryptic subject, but I am trying to do the following (line 
> numbers first) in a shell script:
>
> 15 type=AD
> 16 file=100000_10000_AD.csv
> 17 eval $type_10K=( `cat $file` )
>
> I get the following error message:
> + type=AD
> + file=100000_10000_AD.csv
> combinetab.sh: line 17: syntax error near unexpected token `('
> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>
> Isn't eval supposed to replace $type with AD and then put the contents 
> of $file in an array names AD_10K?

   The first problem is that you are using a variable named
   'type_10K', not 'type'. You need to enclose the variable name in
   braces to separate it from the following character: ${type}_10K.

   The second is that you don't want the command substitution
   performed on the first pass; escape the backticks to prevent that.

   Third, quote the command to prevent filename expansion on the first
   pass, and quote the $file variable (with escaped quotes) to prevent
   expansion on the second pass.

eval "${type}_XX=( \`cat \"$file\"\` )"

   In bash and ksh93 you can dispense with 'cat':

eval "${type}_XX=( \`< \"$file\"\` )"


   Fourth, consider using the positional parameters to make your
   script more portable:

set -f
set -- `cat "$file"`

-- 
   Chris F.A. Johnson, author        <http://cfaj.freeshell.org/shell>
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   ===== My code in this post, if any, assumes the POSIX locale
   ===== and is released under the GNU General Public Licence
0
Chris
9/12/2006 6:02:33 PM
Chris F.A. Johnson wrote:
> On 2006-09-12, Samik R. wrote:
>> Sorry for the cryptic subject, but I am trying to do the following (line 
>> numbers first) in a shell script:
>>
>> 15 type=AD
>> 16 file=100000_10000_AD.csv
>> 17 eval $type_10K=( `cat $file` )
>>
>> I get the following error message:
>> + type=AD
>> + file=100000_10000_AD.csv
>> combinetab.sh: line 17: syntax error near unexpected token `('
>> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>>
>> Isn't eval supposed to replace $type with AD and then put the contents 
>> of $file in an array names AD_10K?
> 
>    The first problem is that you are using a variable named
>    'type_10K', not 'type'. You need to enclose the variable name in
>    braces to separate it from the following character: ${type}_10K.
> 
>    The second is that you don't want the command substitution
>    performed on the first pass; escape the backticks to prevent that.
> 
>    Third, quote the command to prevent filename expansion on the first
>    pass, and quote the $file variable (with escaped quotes) to prevent
>    expansion on the second pass.
> 
> eval "${type}_XX=( \`cat \"$file\"\` )"
> 
>    In bash and ksh93 you can dispense with 'cat':
> 
> eval "${type}_XX=( \`< \"$file\"\` )"
> 
> 
>    Fourth, consider using the positional parameters to make your
>    script more portable:
> 
> set -f
> set -- `cat "$file"`
> 
Thanks for your reply, Chris. I am using bash, so the 3rd comment is 
applicable. Can you elucidate some more (or point to a reference) for 
the fourth comment? I haven't used any of them earlier.

Regards,
-Samik
0
Samik
9/12/2006 6:23:38 PM
On 2006-09-12, Samik R. wrote:
> Chris F.A. Johnson wrote:
>> 
>>    Fourth, consider using the positional parameters to make your
>>    script more portable:
>> 
>> set -f
>> set -- `cat "$file"`
>> 
> Thanks for your reply, Chris. I am using bash, so the 3rd comment is 
> applicable. Can you elucidate some more (or point to a reference) for 
> the fourth comment? I haven't used any of them earlier.

   Using that method, each word of the file is placed into one of the
   positional parameters, $1, $2, ..., ${10}, ${11}, etc., instead of
   into a shell array (which most shells do not support, and is not
   part of the POSIX standard).

-- 
   Chris F.A. Johnson, author        <http://cfaj.freeshell.org/shell>
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   ===== My code in this post, if any, assumes the POSIX locale
   ===== and is released under the GNU General Public Licence
0
Chris
9/12/2006 6:41:04 PM
Chris F.A. Johnson wrote:
> On 2006-09-12, Samik R. wrote:
>> Chris F.A. Johnson wrote:
>>>    Fourth, consider using the positional parameters to make your
>>>    script more portable:
>>>
>>> set -f
>>> set -- `cat "$file"`
>>>
>> Thanks for your reply, Chris. I am using bash, so the 3rd comment is 
>> applicable. Can you elucidate some more (or point to a reference) for 
>> the fourth comment? I haven't used any of them earlier.
> 
>    Using that method, each word of the file is placed into one of the
>    positional parameters, $1, $2, ..., ${10}, ${11}, etc., instead of
>    into a shell array (which most shells do not support, and is not
>    part of the POSIX standard).
> 
I am guessing, then, that the number of elements in the positional 
parameters is not limited (or limited by the system configs)?
And, what does set -f do? In man set, it is written:
-f filename
        Read key bindings from filename.
That does not look appropriate for this purpose.
0
Samik
9/12/2006 8:13:54 PM
On 2006-09-12, Samik R. wrote:
> Chris F.A. Johnson wrote:
>> On 2006-09-12, Samik R. wrote:
>>> Chris F.A. Johnson wrote:
>>>>    Fourth, consider using the positional parameters to make your
>>>>    script more portable:
>>>>
>>>> set -f
>>>> set -- `cat "$file"`
>>>>
>>> Thanks for your reply, Chris. I am using bash, so the 3rd comment is 
>>> applicable. Can you elucidate some more (or point to a reference) for 
>>> the fourth comment? I haven't used any of them earlier.
>> 
>>    Using that method, each word of the file is placed into one of the
>>    positional parameters, $1, $2, ..., ${10}, ${11}, etc., instead of
>>    into a shell array (which most shells do not support, and is not
>>    part of the POSIX standard).
>> 
> I am guessing, then, that the number of elements in the positional 
> parameters is not limited (or limited by the system configs)?

    Limited, I believe, only by available memory. Arguments to a
    command that is not part of the shell are limited by the system.

> And, what does set -f do? In man set, it is written:
> -f filename
>         Read key bindings from filename.
> That does not look appropriate for this purpose.

help set: 
 ...
        -f  Disable file name generation (globbing).


-- 
   Chris F.A. Johnson, author        <http://cfaj.freeshell.org/shell>
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   ===== My code in this post, if any, assumes the POSIX locale
   ===== and is released under the GNU General Public Licence
0
Chris
9/12/2006 10:03:19 PM
Chris F.A. Johnson wrote:
> On 2006-09-12, Samik R. wrote:
>> Sorry for the cryptic subject, but I am trying to do the following (line 
>> numbers first) in a shell script:
>>
>> 15 type=AD
>> 16 file=100000_10000_AD.csv
>> 17 eval $type_10K=( `cat $file` )
>>
>> I get the following error message:
>> + type=AD
>> + file=100000_10000_AD.csv
>> combinetab.sh: line 17: syntax error near unexpected token `('
>> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>>
>> Isn't eval supposed to replace $type with AD and then put the contents 
>> of $file in an array names AD_10K?
> 
>    The first problem is that you are using a variable named
>    'type_10K', not 'type'. You need to enclose the variable name in
>    braces to separate it from the following character: ${type}_10K.
> 
>    The second is that you don't want the command substitution
>    performed on the first pass; escape the backticks to prevent that.
> 
>    Third, quote the command to prevent filename expansion on the first
>    pass, and quote the $file variable (with escaped quotes) to prevent
>    expansion on the second pass.
> 
> eval "${type}_XX=( \`cat \"$file\"\` )"
> 

A continuation of the problem above: now I have stored all the 'type's 
above in an array called 'types'. I want to dynamically report and do 
some calculation from the element of the arrays as declared above. I tried:

declare -a types=( "AD" "KS" )
for type in "${types[@]}"
do
	eval "echo \$\{${type}_XX\[0\]\}"
done

Output:
${AD_XX[0]}
${KS_XX[0]}

I was expecting the values of the above variables from those arrays. I 
even tried nested eval:
	eval "eval `echo \$\{${type}_XX\[0\]\}`"

That produced a blank line. Any idea on what I am missing?

Thanks.
-Samik
0
Samik
9/15/2006 9:15:12 PM
Samik R. wrote:
> Chris F.A. Johnson wrote:
> > On 2006-09-12, Samik R. wrote:
> >> Sorry for the cryptic subject, but I am trying to do the following (line
> >> numbers first) in a shell script:
> >>
> >> 15 type=AD
> >> 16 file=100000_10000_AD.csv
> >> 17 eval $type_10K=( `cat $file` )
> >>
> >> I get the following error message:
> >> + type=AD
> >> + file=100000_10000_AD.csv
> >> combinetab.sh: line 17: syntax error near unexpected token `('
> >> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
> >>
> >> Isn't eval supposed to replace $type with AD and then put the contents
> >> of $file in an array names AD_10K?
> >
> >    The first problem is that you are using a variable named
> >    'type_10K', not 'type'. You need to enclose the variable name in
> >    braces to separate it from the following character: ${type}_10K.
> >
> >    The second is that you don't want the command substitution
> >    performed on the first pass; escape the backticks to prevent that.
> >
> >    Third, quote the command to prevent filename expansion on the first
> >    pass, and quote the $file variable (with escaped quotes) to prevent
> >    expansion on the second pass.
> >
> > eval "${type}_XX=( \`cat \"$file\"\` )"
> >
>
> A continuation of the problem above: now I have stored all the 'type's
> above in an array called 'types'. I want to dynamically report and do
> some calculation from the element of the arrays as declared above. I tried:
>
> declare -a types=( "AD" "KS" )
> for type in "${types[@]}"
> do
> 	eval "echo \$\{${type}_XX\[0\]\}"
> done
>
> Output:
> ${AD_XX[0]}
> ${KS_XX[0]}
>
> I was expecting the values of the above variables from those arrays. I
> even tried nested eval:
> 	eval "eval `echo \$\{${type}_XX\[0\]\}`"
>
> That produced a blank line. Any idea on what I am missing?

try:

    eval "echo \${${type}_XX[0]}"

Xicheng

0
Xicheng
9/15/2006 9:44:25 PM
On 2006-09-15, Samik R. wrote:
> Chris F.A. Johnson wrote:
>> On 2006-09-12, Samik R. wrote:
>>> Sorry for the cryptic subject, but I am trying to do the following (line 
>>> numbers first) in a shell script:
>>>
>>> 15 type=AD
>>> 16 file=100000_10000_AD.csv
>>> 17 eval $type_10K=( `cat $file` )
>>>
>>> I get the following error message:
>>> + type=AD
>>> + file=100000_10000_AD.csv
>>> combinetab.sh: line 17: syntax error near unexpected token `('
>>> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>>>
>>> Isn't eval supposed to replace $type with AD and then put the contents 
>>> of $file in an array names AD_10K?
>> 
>>    The first problem is that you are using a variable named
>>    'type_10K', not 'type'. You need to enclose the variable name in
>>    braces to separate it from the following character: ${type}_10K.
>> 
>>    The second is that you don't want the command substitution
>>    performed on the first pass; escape the backticks to prevent that.
>> 
>>    Third, quote the command to prevent filename expansion on the first
>>    pass, and quote the $file variable (with escaped quotes) to prevent
>>    expansion on the second pass.
>> 
>> eval "${type}_XX=( \`cat \"$file\"\` )"
>> 
>
> A continuation of the problem above: now I have stored all the 'type's 
> above in an array called 'types'. I want to dynamically report and do 
> some calculation from the element of the arrays as declared above. I tried:
>
> declare -a types=( "AD" "KS" )
> for type in "${types[@]}"
> do
> 	eval "echo \$\{${type}_XX\[0\]\}"
> done
>
> Output:
> ${AD_XX[0]}
> ${KS_XX[0]}
>
> I was expecting the values of the above variables from those arrays. I 
> even tried nested eval:
> 	eval "eval `echo \$\{${type}_XX\[0\]\}`"
>
> That produced a blank line. Any idea on what I am missing?

     eval "echo \${${type}_XX[0]}"

-- 
   Chris F.A. Johnson, author        <http://cfaj.freeshell.org/shell>
   Shell Scripting Recipes: A Problem-Solution Approach (2005, Apress)
   ===== My code in this post, if any, assumes the POSIX locale
   ===== and is released under the GNU General Public Licence
0
Chris
9/15/2006 10:13:08 PM
On 9/15/2006 4:13 PM, Chris F.A. Johnson wrote:
> On 2006-09-15, Samik R. wrote:
>> Chris F.A. Johnson wrote:
>>> On 2006-09-12, Samik R. wrote:
>>>> Sorry for the cryptic subject, but I am trying to do the following (line 
>>>> numbers first) in a shell script:
>>>>
>>>> 15 type=AD
>>>> 16 file=100000_10000_AD.csv
>>>> 17 eval $type_10K=( `cat $file` )
>>>>
>>>> I get the following error message:
>>>> + type=AD
>>>> + file=100000_10000_AD.csv
>>>> combinetab.sh: line 17: syntax error near unexpected token `('
>>>> combinetab.sh: line 17: `eval $type_10K=( `cat $file` )'
>>>>
>>>> Isn't eval supposed to replace $type with AD and then put the contents 
>>>> of $file in an array names AD_10K?
>>>    The first problem is that you are using a variable named
>>>    'type_10K', not 'type'. You need to enclose the variable name in
>>>    braces to separate it from the following character: ${type}_10K.
>>>
>>>    The second is that you don't want the command substitution
>>>    performed on the first pass; escape the backticks to prevent that.
>>>
>>>    Third, quote the command to prevent filename expansion on the first
>>>    pass, and quote the $file variable (with escaped quotes) to prevent
>>>    expansion on the second pass.
>>>
>>> eval "${type}_XX=( \`cat \"$file\"\` )"
>>>
>> A continuation of the problem above: now I have stored all the 'type's 
>> above in an array called 'types'. I want to dynamically report and do 
>> some calculation from the element of the arrays as declared above. I tried:
>>
>> declare -a types=( "AD" "KS" )
>> for type in "${types[@]}"
>> do
>> 	eval "echo \$\{${type}_XX\[0\]\}"
>> done
>>
>> Output:
>> ${AD_XX[0]}
>> ${KS_XX[0]}
>>
>> I was expecting the values of the above variables from those arrays. I 
>> even tried nested eval:
>> 	eval "eval `echo \$\{${type}_XX\[0\]\}`"
>>
>> That produced a blank line. Any idea on what I am missing?
> 
>      eval "echo \${${type}_XX[0]}"
> 
Thanks for the replies. Actually my aim is to use the output of the above to print something else. For this purpose I am trying the following (basically generating a CSV):

        for sc in "${SampleCounts[@]}"
        do
                # Form AD line
                Val=`eval "echo \${AD_${sc}[${i}]}"`
                AD_Line=$AD_Line$Val" , "
        done

When I run the script, I get the following error:
Line 105: echo ${KS_${sc}[${i}]}: bad substitution

But if I just leave it at the eval statement, the script prints out the values.  My hunch is that the backtick starts a new process, and there those arrays may not be defined !! Is there any other way out?

Thanks.
-Samik
0
Samik
9/16/2006 5:43:52 AM
On Fri, 15 Sep 2006 23:43:52 -0600, Samik R. 
  <samik@frKKshKll.org> wrote:
>> 
> Thanks for the replies. Actually my aim is to use the output of the 
> above to print something else. For this purpose I am trying the 
> following (basically generating a CSV):
>
>         for sc in "${SampleCounts[@]}"
>         do
>                 # Form AD line
>                 Val=`eval "echo \${AD_${sc}[${i}]}"`
>                 AD_Line=$AD_Line$Val" , "
>         done
>
> When I run the script, I get the following error:
> Line 105: echo ${KS_${sc}[${i}]}: bad substitution
>
> But if I just leave it at the eval statement, the script prints out 
> the values.  My hunch is that the backtick starts a new process, and 
> there those arrays may not be defined !! Is there any other way out?
>
                 eval Val=\${AD_${sc}[${i}]}


-- 
Women, when they have made a sheep of a man, always tell him that he is a
lion with a will of iron.
		-- Honor'e de Balzac
0
Bill
9/16/2006 1:18:42 PM
Reply: