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
How to Recursively Find All Files in Current and Subfolders Based on Wildcard Matching
Performing Http Requests With Curl (Using Proxy)
Command Not Found When Using Sudo
How to Upgrade Glibc from Version 2.12 to 2.14 on Centos
Linux Command to Print Directory Structure in the Form of a Tree
How to Calculate Time For an Asm Delay Loop on X86 Linux
How Is Stack Memory Allocated When Using 'Push' or 'Sub' X86 Instructions
How to Get File Creation Date/Time in Bash/Debian
Pseudo-Terminal Will Not Be Allocated Because Stdin Is Not a Terminal
Adding a New Entry to the Path Variable in Zsh
Lost Httpd.Conf File Located Apache
Makefiles With Source Files in Different Directories
How to Create Docker Overlay Network Between Multi Hosts
Why Does /Bin/Sh Behave Differently to /Bin/Bash Even If One Points to the Other
How to Find Out Which Processes Are Using Swap Space in Linux