Differences between revisions 2 and 53 (spanning 51 versions)
Revision 2 as of 2007-05-07 19:15:30
Size: 3688
Editor: GreyCat
Comment: Why didn't this already link to #48?
Revision 53 as of 2016-04-25 09:34:05
Size: 237
Editor: TimmyStroh
Comment:
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
[[Anchor(faq6)]]
== How can I use associative arrays or variable variables? ==

Sometimes it's convenient to have associative arrays, arrays indexed by a string. Perl calls them "hashes", while Tcl simply calls them "arrays". KornShell93 already supports this kind of array:

 {{{
 # KornShell93 script - does not work with BASH
 typeset -A homedir # Declare KornShell93 associative array
 homedir[jim]=/home/jim
 homedir[silvia]=/home/silvia
 homedir[alex]=/home/alex
 
 for user in ${!homedir[@]} # Enumerate all indices (user names)
 do
     echo "Home directory of user $user is ${homedir[$user]}"
 done}}}

BASH (including version 3.x) does not (yet) support them. However, we could simulate this kind of array by dynamically creating variables like in the following example:

 {{{
 for user in jim silvia alex
 do
     eval homedir_$user=/home/$user
 done}}}

This creates the variables

 {{{
 homedir_jim=/home/jim
 homedir_silvia=/home/silvia
 homedir_alex=/home/alex}}}

with the corresponding content. Note the use of the {{{eval}}} command, which interprets a command line not just one time like the shell usually does, but '''twice'''. In the first step, the shell uses the input {{{homedir_$user=/home/$user}}} to create a new line {{{homedir_jim=/home/jim}}}. In the second step, caused by {{{eval}}}, this variable assignment is executed, actually creating the variable.

Print the variables using

 {{{
 for user in jim silvia alex
 do
     varname=homedir_$user # e.g. "homedir_jim"
     eval varcontent='$'$varname # e.g. "/home/jim"
     echo "home directory of $user is $varcontent"
 done}}}

The {{{eval}}} line needs some explanation. In a first step the command substitution is run:

 {{{
 eval varcontent='$'$varname}}}

becomes

 {{{
 eval varcontent=$homedir_jim}}}

In a second step the {{{eval}}} re-evaluates the line, and converts this to

 {{{
 varcontent=/home/jim}}}

Before starting to use dynamically created variables, think again of a simpler approach. If it still seems to be the best thing to do, have a look at the following disadvantages:

 1. It's hard to read and to maintain.
 1. The variable names must match the regular expression {{{^[a-zA-Z_][a-zA-Z_0-9]*}}} -- i.e., a variable name cannot contain arbitrary characters but only letters, digits, and underscores. In the example above we could not have processed the home directory of a user named {{{hong-hu}}}, because a dash '-' cannot be a valid part of a variable name.
 1. Quoting is hard to get right. If content strings (not variable name) can contain whitespace characters and quotes, it's hard to quote it right to preserve it.
 1. If the program handles unsanitized user input, it can be [#faq48 VERY dangerous]!

Here is the summary. "{{{var}}}" is a constant prefix, "{{{$index}}}" contains index string, "{{{$content}}}" is the string to store. Note that quoting is absolutely essential here. A missing backslash \ or a wrong type of quote (e.g. apostrophes '...' instead of quotation marks "...") can (and probably will) cause the examples to fail:

 * Set variables

  {{{
  eval "var$index=\"$content\"" # index must only contain characters from [a-zA-Z0-9_]}}}

 * Print variable content

  {{{
  eval "echo \"var$index=\$$varname\""}}}

 * Check if a variable is empty

  {{{
  if eval "[ -z "\$var$index\" ]"
  then echo "variable is empty: $var$index"
  fi}}}

You've seen the examples. Now maybe you can go a step back and consider using AWK associative arrays, or a multi-line environment variable instead of dynamically created variables.
Im addicted to my hobby Archery. Seems boring? Not!<<BR>><<BR>>
I to learn German in my free time.<<BR>><<BR>>
<<BR>><<BR>>
Feel free to surf to my blog post: [[https://www.facebook.com/clashofclanshackf/|hack tool clash of clans]]

Im addicted to my hobby Archery. Seems boring? Not!

I to learn German in my free time.



Feel free to surf to my blog post: hack tool clash of clans

BashFAQ/006 (last edited 2023-04-14 06:52:11 by ormaaj)