FlorFlippi
FlorFlippi

Reputation: 21

Variable in variablenames

i have a a couple of variables with a number in its names. e.g

SERVER_IP48_SUBNET
..
SERVER_IP60_SUBNET

And an additional variable

SERVER_IP

Im trying to expand/concatenate them in the following way:

ALLIPs=${SERVER_IP}
  for i in {48..64}; do
    ALLIPs=${ALLIPs},${SERVER_IP${i}_SUBNET}
  done

as you can imagine this script fails saying: Wrong substitution

Does anybody of you know a good solution for this problem? Thanks so far

Upvotes: 1

Views: 60

Answers (3)

glenn jackman
glenn jackman

Reputation: 247142

Use a nameref with bash version 4.3 +

ALLIPs=${SERVER_IP}

for i in {48..64}; do
    declare -n tmp="SERVER_IP${i}_SUBNET"
    ALLIPs+=",$tmp"
done

But you should really be using an array in the first place:

server_ip=0.0.0.0
subnet_ip=(
    [48]=1.1.1.1
    [49]=2.2.2.2
    # ...
    [64]=16.16.16.16
)

all_ips=( "$server_ip" )
for i in {48..64}; do
    all_ips+=( "${subnet_ip[i]}" )
done

(
  IFS=,
  echo "ALLIPs = ${all_ips[*]}"
)
  • Get out of the habit of using ALLCAPS variable names, leave those as reserved by the shell. One day you'll write PATH=something and then wonder why your script is broken.

I just noticed, if you just want a to join the IP addresses with commas, and you're using an array, you don't need a loop at all:

all_ips=$(
  IFS=,
  set -- "$server_ip" "${subnet_ip[@]}"
  echo "$*"
)

Upvotes: 3

Leonardo Dagnino
Leonardo Dagnino

Reputation: 3225

You can use ${!varprefix@} or ${!varprefix*} to expand to all variables with that common prefix (the difference is the same as $@ and $*):

SERVER_IP48_SUBNET=48sub
SERVER_IP49_SUBNET=49sub
SERVER_IP50_SUBNET=50sub

SERVER_IP=1.2.3.4

# set this as empty since !SERVER_IP@ also matches SERVER_IP
ALLIPS=""
for var in "${!SERVER_IP@}"; do
  ALLIPS=$ALLIPS,${!var}
done

This would probably be more practical if you could invert the names like this, since we can only match prefixes:

SERVER_IP_SUBNET_48=48sub
SERVER_IP_SUBNET_49=49sub
SERVER_IP_SUBNET_50=50sub

SERVER_IP=1.2.3.4

ALLIPS=$SERVER_IP
for var in "${!SERVER_IP_SUBNET_@}"; do
  ALLIPS=$ALLIPS,${!var}
done

More info on this feature in the bash manual.

Upvotes: 1

markp-fuso
markp-fuso

Reputation: 35296

One idea:

SERVER_IP48_SUBNET=48sub
SERVER_IP49_SUBNET=49sub
SERVER_IP50_SUBNET=50sub

SERVER_IP=1.2.3.4

ALLIPs=${SERVER_IP}

for i in {48..50}
do
    tmpvar="SERVER_IP${i}_SUBNET"      # build the variable name
    ALLIPs="${ALLIPs},${!tmpvar}"      # indirect variable reference via tmpvar
done

echo "ALLIPs = $ALLIPs}"

This generates:

ALLIPs = 1.2.3.4,48sub,49sub,50sub

Upvotes: 0

Related Questions