How to Generate New Variable Names on the Fly in a Shell Script

How can I generate new variable names on the fly in a shell script?

You need to utilize Variable Indirection:

SAMPLE1='1-first.with.custom.name'
SAMPLE2='2-second.with.custom.name'

for (( i = 1; i <= 2; i++ ))
do
var="SAMPLE$i"
echo ${!var}
done

From the Bash man page, under 'Parameter Expansion':

"If the first character of parameter is an exclamation point (!), a
level of variable indirection is introduced. Bash uses the value of
the variable formed from the rest of parameter as the name of the
variable; this variable is then expanded and that value is used in the
rest of the substitution, rather than the value of parameter itself.
This is known as indirect expansion."

Dynamic variable names in Bash

Use an associative array, with command names as keys.

# Requires bash 4, though
declare -A magic_variable=()

function grep_search() {
magic_variable[$1]=$( ls | tail -1 )
echo ${magic_variable[$1]}
}

If you can't use associative arrays (e.g., you must support bash 3), you can use declare to create dynamic variable names:

declare "magic_variable_$1=$(ls | tail -1)"

and use indirect parameter expansion to access the value.

var="magic_variable_$1"
echo "${!var}"

See BashFAQ: Indirection - Evaluating indirect/reference variables.

Assigning variable values on the fly in bash

Use the declare built-in in bash with -g flag to make it globally available,

#!/bin/bash

while IFS=' = ' read -r key value; do
declare -g $key="$value"
done <OO_CONF.conf

printf "%s %s\n" "${appPackage_name}" "${appPackage_version}"

The idea is to set the IFS to = so to split the lines in the file to read the key and value pairs and then with declare we can create variables on the fly with the below syntax

declare -g <var-name>=<variable-value>

Export a variable with dynamically created name in bash shell script

Export exports variables into the current shell context. By running your script with bash it gets set in that shell's context. You need to source the file to have it run in the current shell context.

source <filename>.sh

Just to show the difference between a sub-shell and source:

[nedwidek@yule ~]# bash test.sh
METASTORE_JDBC_DRIVER_8422
[nedwidek@yule ~]# env |grep META
[nedwidek@yule ~]# source test.sh
METASTORE_JDBC_DRIVER_8143
[nedwidek@yule ~]# env |grep META
METASTORE_JDBC_DRIVER_8143=1

Bash, create multiple arrays with different names using loops

With a recent enough bash, using namerefs:

for (( i=0; i<num; i++ )); do  
declare -n nr="array$i"
declare -a nr=()
done

And then, each time you want to add elements to your array10:

i=10
declare -n nr="array$i"
nr+=( foo bar )

To access the elements you can use the nameref (nr) or the array name, it works the same (as long as you do not modify the nameref attribute):

$ i=10
$ declare -n nr="array$i"
$ printf '%s\n' "${nr[@]}"
foo
bar
$ printf '%s\n' "${array10[@]}"
foo
bar

Think of it as a kind of reference.



Related Topics



Leave a reply



Submit