Assigning dynamic bash variable names using a for loop seq
Kurt Stutsman provides the right pointer in a comment on the question: use Bash arrays to solve your problem.
Here's a simplified example:
groups=() # declare an empty array; same as: declare -a groups
for i in {0..5}; do
groups[i]="group $i" # dynamically create element with index $i
done
# Print the resulting array's elements.
printf '%s\n' "${groups[@]}"
See the bottom of this answer for other ways to enumerate the elements of array ${groups[@]}
.
bash
arrays can be dynamically expanded (and can even be sparse - element indices need not be contiguous)- Hence, simply assigning to element
$i
works, without prior sizing of the array.
- Hence, simply assigning to element
Note how
$i
need not be prefixed with$
in the array subscript, because array subscripts are evaluated in an arithmetic context (the same context in which$(( ... ))
expressions are evaluated).
As for what you did wrong:
group$i=...
is not recognized as a variable assignment by Bash, because - taken literally - group$i
is not a valid identifier (variable name).
Because it isn't, Bash continues to parse until the next shell metacharacter is found, and then interprets the resulting word as a command to execute, which in your case resulted in error message group0=j: command not found
.
If, for some reason, you don't want to use arrays to avoid this problem entirely, you can work around the problem:
By involving a variable-declaring builtin [command] such as declare
, local
, or export
, you force Bash to perform expansions first, which expands group$i
to a valid variable name before passing it to the builtin.
user2683246's answer demonstrates the next best approach by using
declare
(or, if local variables inside a function are desired,local
) to create the variables.Soren's answer uses
export
, but that is only advisable if you want to create environment variables visible to child processes rather than mere shell variables.
Caveat: With this technique, be sure to double-quote the RHS in order to capture the full value; to illustrate:
i=0; declare v$i=$(echo 'hi, there'); echo "$v0" # !! WRONG -> 'hi,': only UP TO 1ST SPACE
i=0; declare v$i="$(echo 'hi, there')"; echo "$v0" # OK -> 'hi, there'
Other ways to enumerate the groups
array created above:
# Enumerate array elements directly.
for element in "${groups[@]}"; do
echo "$element"
done
# Enumerate array elements by index.
for (( i = 0; i < ${#groups[@]}; i++ )); do
echo "#$i: ${groups[i]}"
done
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.
Bash declaring variable with a number inside a for loop
Without an array, you need to use the declare
command:
i=0
for int in $ints; do
i=$((i +1))
declare "intf$i=$int"
done
With an array:
intf=()
for int in $ints; do
intf+=( $int )
done
Increment variable name results in command not found
To achieve the outcome required, the use of arrays are needed and so:
#!/bin/bash
for i in $(seq 5)
do
var[$i]="number is $i"
done
for i in "${var[@]}"
do
echo "$i"
done
Set the index and values for the array var accordingly and then loop through the array and print the values.
Related Topics
Read a File and Split Each Line into Multiple Variables
Hosting Two Website Under One Web App - Azure Services
Start Jboss 7 as a Service on Linux
Differencebetween Ld_Library_Path and -L at Link Time
Linux Configure/Make, --Prefix
How to Properly Set Java_Home in /Etc/Environment
Tracking Actively Used Memory in Linux Programs
Gvim Redraw Issues with Virtual Box and Windows 7 Host
Adding Support for Menuconfig/Kconfig in My Project
How to Set Process Group of a Shell Script
Bash Shell Script Variable Assignment
How to Write a Linux Bash Script That Tells Me Which Computers Are on in My Lan
What Is a Way to Read Man Pages in Vim Without Using Temporary Files
What's the Meaning of a ! Before a Command in the Shell
How to Calculate the Mean of a Column
Check If Vt-D/Iommu Has Been Enabled in The Bios/Uefi
Sed Replace In-Line a Specific Column Number Value at a Specific Line Number