Resolve variable inside another variable

Hello Everyone,

I am trying to resolve a variable inside another variable.Let me go straight to the example.

Input:

Query=$Table_1 Join $Table_2

(Query itself is a variable here)

Now for two different cases I am assigning different values to Table_1 and Table_2

Case 1:
Table_1=tbl1_c1
Table_2=tbl2_c1

After this I want to write a command here so that when I echo Query it should show like:

echo $Query

tbl1_c1 Join tbl2_c1

I suppose this can be done with eval , and I have tried few options as well but I could not achieve the desired output.

Could you please help.

Thanks,
Vinay

This won't work for you?

Table_1=tbl1_c1
Table_2=tbl2_c1
Query="$Table_1 Join $Table_2"
echo "$Query"
1 Like

I'm not quite sure what the issue you're having is. It seems the solution Bartus posted should work. For funsies though, you could probably do it like this:

(19:12:02\[root@DeCoBoxOmega)
[~/Desktop]$ tables=( "tb1|tb2" "tb3|tb4") #create an array with pairs of tables

(19:12:10\[root@DeCoBoxOmega)
[~/Desktop]$ echo "${tables[0]%%|*}" #use string manipulation to play around with one
tb1

(19:12:26\[root@DeCoBoxOmega)
[~/Desktop]$ echo "${tables[1]##*|}" #Or the other
tb4

(19:12:34\[root@DeCoBoxOmega)
[~/Desktop]$ query="${tables[0]%%|*} Join ${tables[1]##*|}" #Use these arrays to create a variable

(19:12:46\[root@DeCoBoxOmega)
[~/Desktop]$ echo ${query} #and bob's your uncle
tb1 Join tb4

(19:12:50\[root@DeCoBoxOmega)
[~/Desktop]$
1 Like

Hi
Maybe that's what you mean ?

$ Table_1=tbl1_c1
$ Table_2=tbl2_c1
$ Query='$Table_1 Join $Table_2'
$ echo $Query
$Table_1 Join $Table_2
$ eval echo $Query
tbl1_c1 Join tbl2_c1
1 Like

Thanks everyone for helping me understand the basics.I used m_eval option and it worked.

I will try out other options as well and will get back if there is any problem.

Thanks again.

eval is a giant security hole.

If `rm -Rf ~/` ends up in your variables somehow, eval will execute it.

Please explain what you're actually trying to do so we can show you how to avoid the eval.

Corona,

I wanted to resolve a variable (say Table_1) which again is inside another varible (say Query = $Table_1 Join).Using double quotes (") I was able to it it for sample examples.

Now when I try to implement the same in the actual problem statement I have, it throws error.

 
Code:
 
resolvedQuery=echo "$mainQuery"
 
Error:
 
varibale_test.ksh[40]: <big variable name here> : name too long

And yes actually variable here is big. It is a sql query.

I tried below as well.

 
resolvedQuery=$( eval echo $(echo $mainQuery))

This works well , only problem is single quote characters are dissolved after resolution.

Example:

 
Query= $Table_1 Join $Table_2 where condition='abc'

After resolution it becomes:

 
Query=t1 Join t2 where condition=abc

Can you please help me find a way , to resolve big length variable keeping single quote (') intact.

Thanks,
Vinay

Depending on the shell, you can do this with ${!VARNAME}. BASH or new versions of ksh can do this.

I still don't know why you want to do that, though.

You haven't explained your actual problem -- just the way you're hellbent on solving it. The kind of thing you're trying to do is something that's usually avoided, and for good reason.

As such, it's very difficult to offer helpful advice.

Corona,

Thanks for the reply.
I am sorry that you had ask it again :(. I thought instead of explaining the whole problem statement , it would be good if I just ask what is it that I am facing problem which is resolving parameters.

Here is the actual problem statement I am trying to solve.

I have a SQL query. This query has variables which I want to resolve at run-time.Query is itself a variable. And the parameters(variables inside it) for this Query will be assigned values just before I write the command(This command I am struggling with) to resolve the Query.

Once the Query is resolved I will put that in command line (m_db command).

During this process I have faced problem which I stated.I hope my previous post will make you sense now.

Could you please help me out with below two problems:

  1. How to overcome this error : variable name too long
  2. How to retain single quote character while resolving variable.
    (I have given detail with example in previous post)

I am using Korn Shell.

Thanks,
Vinay

:wall: Why do you want to resolve variables inside variables?

The way to avoid the inevitable problems of that kind of doublethink is to not do that. You're finding it ugly and fraught with problems because it is ugly and fraught with problems. There's not a "right way" -- you're twisting the shell in directions it's not supposed to go.

If you describe the problem you're actually trying to solve -- the thing your program is actually supposed to do! -- there's probably a way which avoids the need for that.

Corona,

I tried to explain my actual purpose in previous post.
Let me go to the problem statement directly.

Suppose this is the Query.

echo "$Query"

Select '$ENV',t1.field1,t2.field2
from $table1 t1,$table2 t2
where t1.field1='$var1'
and t2.field1='$var2'

This Query is actually big (30+ lines)

Now I have below assignments of variables:

ENV='DEV'
table1='ABC'
table2='XYZ'
var1='Hi'
var2='Bye'

Then I use below command to resolve:

resolvedQuery= echo "$Query"

I am expecting below output:

echo $resolvedQuery

Select 'DEV',t1.field1,t2.field2
from ABC t1,XYZ t2
where t1.field1='Hi'
and t2.field1='Bye'

But it throws below error:

variable name too big

And if I try below:

resolvedQuery=$(eval echo $(echo $Query))

It resolved without error but then I have lost single quote character in query.
Please see below output for clarification.

Select DEV,t1.field1,t2.field2
from ABC t1,XYZ t2
where t1.field1=Hi
and t2.field1=Bye

I hope I have made my case now :wink:

Please advise.

Thanks

You either can't or won't tell me what the purpose of your program is. Nobody writes a program to "substitute in a variable", presumably that program has some actual use to you.

Fine, I'll do what I can without it.

You are doing it exactly backwards, which is why you are having so many problems. Set the variables first. Then make your query, letting it substitute the variables right then and there. That is the way variables are supposed to work. You'll get exactly what you want, quotes intact.

If possible, use it directly instead of storing it in a variable -- 30 lines is a lot to put in one variable, and you want to avoid splitting and accidental substitution anyway. You can use a here-document to stream something into a program, variables will substitute inside it:

databaseprogram <<EOF
Select '$ENV',t1.field1,t2.field2
        from $table1 t1,$table2 t2
        where t1.field1='$var1'
        and t2.field1='$var2'
EOF

Corona,

I have a query and I want to run it passing parameters at runtime. For which I tried the way I explained below and believe me that is the purpose of program.

I need to run the Query(s) in a loop.There is metadata table which has one entry for each Id. Each Id has a Query attached.Query is a field in metadata table which I get passing Id to the table.This way I get corresponding Query for an Id.
Now this Query I cannot use directly.
The parameters (clause in query) I need to put in the query at runtime.These values ( values of the variables which I need to put in Query) also I will get from the same metadata table (where I got Query for an Id from). Again I will pass the Id and will the corresponding values.These values(in my example var1,var2,table1,table2) I need to pass in Query actually.

One more complexity here. I will get two set of values for each Id.
One set is for say set A and another is for set B.
Number of parameters in both sets will be same.
The value of these parameters I need to resolve. I assign values for the query from parameter set A first , resolve query and run it.
Then I assign values for the query for parameter set B then resolve the query and run it.

Ok , obviously same query will be used for an Id no matter how many set of values we have.

This is not a standard way , but a way which I am following. Please advise how can I improve this so that I do not get those errors.

Thanks

Okay.

Okay.

Now we're getting somewhere.

Instead of using shell variables, I might try using a language which has associative arrays, like awk, so values can easily be looked up and a string easily assembled without substitution anywhere you don't want it. This can be embedded in the shell script itself seamlessly, and will avoid the pitfalls of looking up variable names in the shell.

What does this metadata table look like, and how are you retrieving from it? What output would you want for given input?

Metadata table contain
1.set of values (numeric as well String) which are the constituents of Query for every Id.
2. Query for every Id.

Id is the primary key in table.

I use m_db command to run sql query in Unix.

Input to program - metadata table
Input to meatadata table - Id

Output from metadata table - multiple (2) set of values and Query
Output from program - Data sets for every Id