LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 12-11-2009, 10:34 PM   #1
DevonB
LQ Newbie
 
Registered: Dec 2009
Posts: 27

Rep: Reputation: 1
BASH - How to access a variablized variable?


Greetings everone, I'm new here and need a bit of help.

I'm having an issue trying to pull the value out of a variable I have set. I have a loop that its variable is part of the name of a different variable. I can set it, but I cannot grab its value. My problem is, I don't know how to force BASH to treat the entire block of text as a single variable; it keeps breaking it into two. How can I make it treat it as one? Example -

Code:
STRING1=MyName
SOME_VALUE=Devon

STRING2_$STRING1_REST_OF_STRING=SOME_VALUE < this sets properly.
My problem is, how do I access it? If I try this -

echo $STRING2_${STRING1}_REST_OF_STRING, it treats is as two variables. If I print it out, I get basically

${STRING1}_REST_OF_STRING

with the $STRING2_ missing. I know it's doing it because it's splitting my variable into $STRING2_ as one variable (which is set to nothing) and ${STRING1}_REST_OF_STRING as a separate variable, which also is set to nothing.

If I try -

${STRING2_${STRING1}_REST_OF_STRING}

I get an error about bad substitution.

I'm assuming since I can set the "big" variable, there is some built-in that I can use to force it to treat it as one variable and not two separate varaibles, but what is it? Google has left me empty handed so far. I've tried single quotes, double quotes, I've even got it to set to another variable properly, but then it treats that variable as a literal, and I cannot get it to print out its value. For example -

Code:
NEW_STRING=`\$STRING_2${STRING1}_REST_OF_STRING`
It will print out the literal "$STRING_2MyName_REST_OF_STRING", but I can't get to the value I set it to, which is Devon.

Help, please!

Devon

Last edited by DevonB; 12-11-2009 at 10:35 PM.
 
Old 12-11-2009, 10:44 PM   #2
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
Hopefully this will help you:

Code:
sasha@reactor:~$ STRING1=MyName
sasha@reactor:~$ SOME_VALUE=Devon
sasha@reactor:~$ newvar=$(eval echo \${STRING2_$STRING1_REST_OF_STRING=$SOME_VALUE})
sasha@reactor:~$ echo $newvar
Devon
sasha@reactor:~$
sasha@reactor:~$ eval echo \${STRING2_$STRING1_REST_OF_STRING}             
Devon
sasha@reactor:~$
Sasha

Last edited by GrapefruiTgirl; 12-11-2009 at 10:46 PM.
 
1 members found this post helpful.
Old 12-11-2009, 11:22 PM   #3
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
please, try to use arrays/associative arrays, now that newer bash supports them.
Code:
declare -a array
declare -A dict
STRING1=MyName
SOME_VALUE=Devon
array[0]=$SOME_VALUE
dict["STRING2_$STRING1_REST_OF_STRING"]=$SOME_VALUE

#print array value
echo ${array[0]}

#print associative array
echo ${dict[@]}
echo ${array["STRING2_$STRING1_REST_OF_STRING"]}

Last edited by ghostdog74; 12-11-2009 at 11:24 PM.
 
Old 12-12-2009, 12:02 AM   #4
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
If you already have or you can install bash 4.0, use associative arrays as ghostdog74 also suggested. It will really simplify things.

However if you still want to know how, perhaps you can play around with the ${!VAR} feature of bash.

Code:
VAR=data
VARPTR=VAR
echo ${!VARPTR}
 
Old 12-12-2009, 01:30 AM   #5
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by konsolebox View Post
If you already have or you can install bash 4.0, use associative arrays as ghostdog74 also suggested. It will really simplify things.

However if you still want to know how, perhaps you can play around with the ${!VAR} feature of bash.

Code:
VAR=data
VARPTR=VAR
echo ${!VARPTR}
should be careful when using this. try this
Code:
$ VAR=data
$ VARPTR=VAR
$ VARPTR1=VARPTR
$ echo ${!VARPTR1}
VAR
what do you think ${!VARPTR1} should be?
 
Old 12-14-2009, 04:39 AM   #6
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
hmmm.. my guess :-).. VAR also no? it's obvious why? .. to get data using VARPTR1.. we need to reparse it:
Code:
TEMP=${!VARPTR1}
echo "${!TEMP}"
or
Code:
eval echo \"\${!${!VARPTR1}}\"
-- edit --

and if i'm to use another variable pointer, i'll call it VARPTRPTR although in my projects i alwayse use *VAR like:
Code:
ARRAY=()
ARRAYVAR=ARRRAY
ARRAYVARVAR=ARRAYVAR
such things does not appear much in my codes though. i just gave an example.

Last edited by konsolebox; 12-14-2009 at 04:46 AM.
 
Old 12-14-2009, 04:40 AM   #7
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
and VAR is "data" , right?
 
Old 12-14-2009, 04:48 AM   #8
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
yup. ... i sort of don't get the point. they're just variables pointing to strings right? .. not really pointers.. only ${!PARAM} does the magic.
 
Old 12-14-2009, 04:55 AM   #9
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by konsolebox View Post
hmmm.. my guess :-).. VAR also no? it's obvious why? .. to get data using VARPTR1.. we need to reparse it:
that's where the problem lies. At run time, you won't know how many levels you are going to parse. the syntax "${!<param>}" somehow is not used like that in the context of references.
 
Old 12-14-2009, 05:02 AM   #10
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
Well it's enough if you're after only 1 level of reference. I don't really mean we should consider the method. I just gave the example for the single level.. It's up for the OP what he'll do .. either he still consider the re-reference thing or use eval.. but as I said before it's also better if he just use the hashes. You'll usually have to decide what other method to use when you're after at least more than 2 levels. I don't do that in my codes.
 
Old 12-14-2009, 10:19 AM   #11
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
OK, the OP hasn't been back since asking this question.. Rather than perpetuate the discussion of 'this way is better, that way is better', I think we should wait for the OP's return and see if he/she has any input about the methods above. We don't even know what OS or shell the OP is using.

Frankly though, I don't see what was so difficult or horrid about my first reply, nor why using arrays would be (any/much) better. And, much of the above ideas imply not only a Bash shell, but assume that the OP has a new Bash shell, or is willing to get one; we know where assuming can lead us

@ Ghostdog, respectfully: your shell scripting help has many times proven very helpful to myself and others, and I appreciate that -- you're knowledgeable in this area, no question -- but on this subject of arrays, I'm getting a little bit of mixed messages from you. In this thread, you're suggesting use of arrays, yet in this other thread of mine you suggest I avoid (extensive use of) arrays and/or switch languages if I need a lot of array-like constructs so why the difference? Was it the desire for POSIX-ness, or for portability, that your suggestion in that other thread was different? FWIW I'm working on a solution to that other thread today -- an update later I hope.

Thanks for clarification -- on with the show,

Sasha

Last edited by GrapefruiTgirl; 12-14-2009 at 10:21 AM.
 
Old 12-14-2009, 10:45 AM   #12
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Quote:
Originally Posted by GrapefruiTgirl View Post
@ Ghostdog, respectfully: your shell scripting help has many times proven very helpful to myself and others, and I appreciate that -- you're knowledgeable in this area, no question -- but on this subject of arrays, I'm getting a little bit of mixed messages from you. In this thread, you're suggesting use of arrays, yet in this other thread of mine you suggest I avoid (extensive use of) arrays and/or switch languages if I need a lot of array-like constructs so why the difference? Was it the desire for POSIX-ness, or for portability, that your suggestion in that other thread was different? FWIW I'm working on a solution to that other thread today -- an update later I hope.
you misunderstood what i am trying to say in that thread. You mentioned you are starting a project which makes use of arrays, and that you worry about problems of shells not supporting arrays. Instead of worrying about how if you use arrays in your script and being not able to work for other shells that don't support it, I suggested to you to use a different programming language than the shell, such as Python (or Perl if you like). Python/Perl data types (arrays, variables, dictionaries/hashes) have been pretty standard since olden times, so you can be 99% sure that if you write your code in newer version of language, it can be used in older ones (data types/structures).

whereas coming back to this thread, its a different problem. OP is trying to set a variable name using another variable, which essentially in programming terms, is equivalent to assigning values to arrays.
consider this
Code:
a=0
int_$a=2
don't you think it cleaner to use arrays
Code:
declare -a array
i=0
array[$i]=2
now, whenever you need to call element 1's value, you just do array[0]. No need to invoke eval. Variables, after all, after just names for memory addresses, so are array indexes.

of course, if the OP's shell doesn't support arrays/assoc arrays, then too bad. use the eval method.

Last edited by ghostdog74; 12-14-2009 at 10:59 AM.
 
Old 12-14-2009, 12:23 PM   #13
GrapefruiTgirl
LQ Guru
 
Registered: Dec 2006
Location: underground
Distribution: Slackware64
Posts: 7,594

Rep: Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551Reputation: 551
OK, gotcha -- thanks for that clarification. To our detriment, I had not been clear enough in that other thread though: I should have made it more clear that I am not "just starting" that project, but rather it's been ongoing for a long time, and just lately, I began considering making it more portable, but it already has made extensive use of arrays, so I'm looking at a "conversion" issue, rather than starting a fresh project in a portable way.

My apology for the lack of clarity there.

Kind regards,
Sasha
 
Old 12-14-2009, 06:34 PM   #14
ghostdog74
Senior Member
 
Registered: Aug 2006
Posts: 2,697
Blog Entries: 5

Rep: Reputation: 244Reputation: 244Reputation: 244
Ah, i see. If you are still going to continue writing in shell, there are some books that you can take reference to. eg "Beginning Portable shell scripting" etc. Or search on the internet for articles about that. But personally, i think it will be worthwhile to port your project to Python, (or Perl). Besides making use of their good data structures, there are vast amount of libraries you can use for your project without reinventing the wheel. anyway, its up to you.
 
Old 12-14-2009, 06:44 PM   #15
chrism01
LQ Guru
 
Registered: Aug 2004
Location: Sydney
Distribution: Centos 6.8, Centos 5.10
Posts: 17,260

Rep: Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328Reputation: 2328
I can definitely confirm that arrays are one of the 3 basic data types (scalar, array, hash) in Perl & as he hinted, there's a huge library of pre-written modules avail at search.cpan.org.
Note that a lot of those are already in the std Perl install http://perldoc.perl.org/perlfaq3.htm...n-my-system%3F
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
-bash: HISTSIZE: readonly variable -bash: HISTFILESIZE: readonly variable deathsfriend99 Linux - Newbie 4 12-08-2009 01:51 PM
How to get variable from text file into Bash variable mcdef Linux - Software 2 06-10-2009 02:15 PM
Problem with bash script - variable name within variable name steven.c.banks Linux - Newbie 3 03-10-2009 04:08 AM
BASH: instad of echo-ing, I just want to assing to a bash variable... how?? rylan76 Linux - Newbie 9 11-28-2008 09:46 AM
bash scripting need help getting a variable of a variable dovo Programming 6 10-29-2008 02:30 PM


All times are GMT -5. The time now is 03:00 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration