2

Say I have two variables;

var_one_string=foo
var_two_string=bar

How would I accomplish something like this (pseudo code examples);

EXAMPLE 1

for i in one two; do
  echo $var_${i}_string
done
# Desired output
foo
bar

EXAMPLE 2

for i in one two; do
  echo $var_$(echo ${i})_string
done
# Desired output
foo
bar

I understand that this is bad substitution, I am just wondering if there is a way to nest a string within another variable call?

EDIT: I was able to get it to work

var_one_string=foo
var_two_string=bar

for i in $(echo ${!var_*}); do
    echo ${!i}
done
foo
bar
s3d83d
  • 41
  • 2
  • 9

2 Answers2

2

Use the declare built-in along with indirect-variable expansion in bash. First define the elements of for the dynamic nature in an array as

#!/bin/bash

list=(one two)
unset count

for var in "${list[@]}"; do 
    declare var_${var}_string="string"$((++count))
done

and now access the created variables using indirect expansion

for var in "${list[@]}"; do 
    dymv="var_${var}_string"
    echo "${!dymv}"
done

and never use eval for this requirement. Could be dangerous because of unlikely code-injection possibility with a harmful command.

Inian
  • 80,270
  • 14
  • 142
  • 161
  • Ok, so you showed me that my question wasn't what I intended, does it still work with my updated question. (i.e. var_one_string=string1) – s3d83d May 11 '17 at 15:07
  • @s3d83d: Check my update – Inian May 11 '17 at 15:12
  • Hahaha, you are showing me that I am horrible at asking questions. Again, not my intention for a pattern in var sets. How about my updated question. – s3d83d May 11 '17 at 15:14
  • @s3d83d: You need to assign the variable value to `declare` on the fly. Is it ok if the script asks the variable to the user and stores it? – Inian May 11 '17 at 15:19
  • I would prefer if it was autonomous. So far user input is restricted to y/n....would like to keep it there. – s3d83d May 11 '17 at 15:21
  • No. Where I'm calling in the script, user interaction wouldn't really work. – s3d83d May 11 '17 at 15:25
  • @s3d83d: so how are the variables defined. I need a way to dynamically access those variable values. May be can you have the values foo bar also in an array – Inian May 11 '17 at 15:26
  • The part that makes it tricky in my script is that I have variable like; var_changingword_${key}=data where key=$(echo -e "$(printf '%04x' $RANDOM $RANDOM)"). For the life of the script $key never changes. – s3d83d May 11 '17 at 15:42
  • @s3d83d: The changingword/key variables are available at the time `declare` is called. Only the data part is missing. fix that – Inian May 11 '17 at 15:43
  • Thanks for the help Inian, I was able to get it to work. – s3d83d May 11 '17 at 15:58
0

Basically, you can use eval: echo $(eval '$var_'"${i}")

But you can also use a dictionnary:

declare -A vars
vars=( ["one"]="number-one" ["two"]="number-two" )
i="one"
echo "${vars[${i}]}"
LoganMzz
  • 1,597
  • 3
  • 18
  • 31
  • Ok, so an array would work with my "original" example. However, what if the nested variable construct was something more like this; var_one_string=string1; echo $var_${i}_string. I'll add this to my original question. – s3d83d May 11 '17 at 14:57