LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - General (https://www.linuxquestions.org/questions/linux-general-1/)
-   -   About arrays (https://www.linuxquestions.org/questions/linux-general-1/about-arrays-909360/)

flashback 10-21-2011 11:03 AM

About arrays
 
Hi all, i have my first question here in LQ, and it's related to arrays and bash.
Here we go:
is it possible to use instead of the plain following:

echo ${test[0]}

to read the first element of
test, that is obviously a previously declared array,
something like:

echo ${$myvar[0]}

where myvar is a variable containing the name of an array ?
Should i instead play with eval and string concatenation ?

Thanks for any answer,
Roberto.

crts 10-21-2011 12:02 PM

Welcome to LQ,

not sure about what exactly you are trying to achieve but is this what you are trying to do?
Code:

$ array=( one two )
$ one=success
$ eval echo "\${${array[0]}}"
success

I do not think that you can avoid the 'eval' in this case.

MTK358 10-21-2011 12:11 PM

Quote:

Originally Posted by crts (Post 4504502)
not sure about what exactly you are trying to achieve but is this what you are trying to do?

He is trying to use the contents of a variable as an array name.

crts 10-21-2011 12:26 PM

Quote:

Originally Posted by MTK358 (Post 4504510)
He is trying to use the contents of a variable as an array name.

In this case:
Code:

$ name=array
$ array=( one two )
$ eval echo \${$name[0]}
one

Or better:
Code:

$ eval echo \${${name}[0]}
The curly braces make it easier to see that 'name' is not an array but a normal variable.
Still, 'eval' cannot be avoided.

David the H. 10-21-2011 01:29 PM

Please use [code][/code] tags around your code, to preserve formatting and to improve readability.


Your question really has little to do with arrays specifically. What you're asking for is called indirect referencing.

eval is one way to do it, but it's certainly not recommended usually. eval has security issues. In a nutshell, you should never use it on any string where you don't have complete control over the contents, and can't determine what the actual eval'd command would look like and do.

http://mywiki.wooledge.org/BashFAQ/048

Depending on what your final purpose is, there are a few other, probably better, options. To start with, bash has a dedicated indirect reference expression "${!variable}". To re-use the above example:

Code:

$ name=array
$ array=( one two )
$ echo "${!name[0]}"
one

Note however that using ${!name[@]} or ${!name[*]} will output a list of the all the existing index numbers of that array instead.

Edit: D'oh! I just realized this doesn't quite work as expected. ${!name[0]} evaluates to "one", because it's the same as ${!name}. But ${!name[1]} does not evaluate to anything, as it's trying to reference a non-existent array entry. In short, it will work when expanding simple variables, but can't be used for dynamic array names.

You could however indirectly reference the index number instead, although now we're getting really nested!


Code:

$ foo=0
$ name=foo
$ array=( one two )
$ echo "${array[${!name}]}"
one

There are also now associative arrays, which are arrays that use character strings as indexes, rather than numbers. Most of the things that used to need indirect referencing can now be handled better with them.

Code:

$ declare -A array
$ array=( [one]=foo [two]=bar )

$ num=( one two )

$ echo "${array[${num[0]}]}"
foo
$ echo "${array[${num[1]}]}"
bar

More on indirect referencing here :
http://mywiki.wooledge.org/BashFAQ/006

flashback 10-24-2011 02:53 AM

Thanks
 
Thanks to everybody for you answers, i have now all the hints i need to proceed.
MTK358 was right, in fact i was trying to use the contents of a variable as an array name.
Thanks again to crts and David.

Roberto.

p.s. next time i'll use [code] :)


All times are GMT -5. The time now is 06:52 PM.