Home > Net >  BASH assign value in an ARRAY dynamically
BASH assign value in an ARRAY dynamically

Time:12-29

I want to assign the value of an array dynamically, and when I change the variable the array changes automatically.

var=5  
arr=( $\[$var-1\] $var $\[$var 1\] )  
echo ${arr\[@\]}  
var=10  
echo ${arr\[@\]}

result

4 5 6
4 5 6 

I wanted

4 5 6 
9 10 11

CodePudding user response:

Try something like this:

v1=abc
v2=efd
v3=ghj

arr=( v1 v2 v3 )

for i in ${arr[@]}; { echo ${!i}; }
abc
efd
ghj

Now lets change values of those vars:

v1=123
v2=456
v3=789

$ for i in ${arr[@]}; { echo ${!i}; } 
123
456
789

CodePudding user response:

While such automatic updates are perfectly common in spreadsheet applications, Bash doesn’t work that way. If you want to recalculate a few values based on formulas, you have to explicitly tell Bash to do so. The example below generates the outputs that you expect and defines a function called recalculate that you need to call after changes to the formulas or the formulas’ input variables. The rest of the trick is based around how integer evaluation works in Bash.

recalculate() {
  local -n source="$1" target="$2"
  target=("${source[@]}")
}

formulas=('var - 1' 'var' 'var   1')
declare -ai arr

var=5
recalculate formulas arr
echo "${arr[@]}"          # 4 5 6

var=10
recalculate formulas arr
echo "${arr[@]}"          # 9 10 11

(It would be awesome if Bash had an additional pseudo-signal for the trap command, say assignment, which could work like trap 'echo "variable ${1} set to ${!1}"' assignment, but AFAIK, there is no such functionality (plus no separate argument handling in trap); hence the strikethrough. Without that kind of functionality, a function like recalculate might be the closest you can get to the updates you asked for.)

A slightly more elaborate version of recalculate could also (1) handle sparse arrays of formulas correctly, i.e. guarantee to store results under the same indices under which the corresponding formulas were found, and (2) introduce a “reserved” variable name, say index, which can occur in the formulas with an obvious meaning. Just for fun, “because we can”:

recalculate() {
  local -n source="$1" target="$2"
  local -i index
  target=()
  for index in "${!source[@]}"; do
    target[index]="${source[index]}"
  done
}

formulas[1]='index * var - 1'
formulas[3]='index * var'
formulas[5]='index * var   1'
declare -ai arr

var=5
recalculate formulas arr
echo "${arr[@]@A}"  # declare -ai arr=([1]="4" [3]="15" [5]="26")

var=10
recalculate formulas arr
echo "${arr[@]@A}"  # declare -ai arr=([1]="9" [3]="30" [5]="51")
  •  Tags:  
  • bash
  • Related