BASH:如何在循环中创建动态数组名称
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16523581/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
BASH: how to create a dynamic array name in a loop
提问by Peter Pan
here's what I tried:
这是我尝试过的:
n=0
for i in aaa bbb ccc; do
array${i}[$n]=$(date "+%N")
((++n))
done
n=0
for i in aaa bbb ccc; do
echo ${array${i}[$n]}
((++n))
done
any ideas how to make the dynamic array name work? thanks a lot!
任何想法如何使动态数组名称工作?多谢!
回答by Sir Athos
You can use indirect expansion:
您可以使用间接扩展:
#!/bin/bash
# create the arrays
n=0
for i in aaa bbb ccc; do
let array$i[$n]=$(date "+%N")
((++n))
done
# display what we did
n=0
for i in aaa bbb ccc; do
var=array$i[$n]
echo ${!var}
((++n))
done
Note that this will only create array variables arrayaaa[0], arraybbb[1]and arrayccc[2], and not(as you might expect) arrayaaa[0], arrayaaa[1], arrayaaa[2], arraybbb[0], arraybbb[1], arraybbb[2], arrayccc[0], arrayccc[1], and arrayccc[2].
请注意,这只会创建数组变量arrayaaa[0]、arraybbb[1]和arrayccc[2],而不是(如您所料)arrayaaa[0]、arrayaaa[1]、arrayaaa[2]、arraybbb[0]、arraybbb[1]、arraybbb[2]、arrayccc[0]、arrayccc[1]和arrayccc[2]。
回答by NOPx90
This is how you would create a dynamically named variable (bash version < 4.3).
这是创建动态命名变量的方式(bash 版本 < 4.3)。
# Dynamically named array
my_variable_name="dyn_arr_names"
eval $my_variable_name=\(\)
# Adding by index to the array eg. dyn_arr_names[0]="bob"
eval $my_variable_name[0]="bob"
# Adding by pushing onto the array eg. dyn_arr_names+=(robert)
eval $my_variable_name+=\(robert\)
# Print value stored at index indirect
echo ${!my_variable_name[0]}
# Print value stored at index
eval echo ${$my_variable_name[0]}
# Get item count
eval echo ${#$my_variable_name[@]}
Below is a group of functions that can be used to manage dynamically named arrays (bash version < 4.3).
下面是一组可用于管理动态命名数组的函数(bash 版本 < 4.3)。
# Dynamically create an array by name
function arr() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
# The following line can be replaced with 'declare -ag =\(\)'
# Note: For some reason when using 'declare -ag ' without the parentheses will make 'declare -p' fail
eval =\(\)
}
# Insert incrementing by incrementing index eg. array+=(data)
function arr_insert() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
eval [$\(\(${#[@]}\)\)]=$2
}
# Update an index by position
function arr_set() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
eval []=${3}
}
# Get the array content ${array[@]}
function arr_get() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
eval echo ${[@]}
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_at() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
[[ ! "" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; }
local v=
local i=
local max=$(eval echo ${\#[@]})
# Array has items and index is in range
if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]]
then
eval echo ${$v[$i]}
fi
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_count() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
local v=
eval echo ${\#[@]}
}
array_names=(bob jane dick)
for name in "${array_names[@]}"
do
arr dyn_$name
done
echo "Arrays Created"
declare -a | grep "a dyn_"
# Insert three items per array
for name in "${array_names[@]}"
do
echo "Inserting dyn_$name abc"
arr_insert dyn_$name "abc"
echo "Inserting dyn_$name def"
arr_insert dyn_$name "def"
echo "Inserting dyn_$name ghi"
arr_insert dyn_$name "ghi"
done
for name in "${array_names[@]}"
do
echo "Setting dyn_$name[0]=first"
arr_set dyn_$name 0 "first"
echo "Setting dyn_$name[2]=third"
arr_set dyn_$name 2 "third"
done
declare -a | grep "a dyn_"
for name in "${array_names[@]}"
do
arr_get dyn_$name
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name by index"
# Print by index
for (( i=0 ; i < $(arr_count dyn_$name) ; i++ ))
do
echo "dyn_$name[$i]: $(arr_at dyn_$name $i)"
done
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name"
for n in $(arr_get dyn_$name)
do
echo $n
done
done
Below is a group of functions that can be used to manage dynamically named arrays (bash version >= 4.3).
下面是一组可用于管理动态命名数组的函数(bash 版本 >= 4.3)。
# Dynamically create an array by name
function arr() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -g -a =\(\)
}
# Insert incrementing by incrementing index eg. array+=(data)
function arr_insert() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=
r[${#r[@]}]=
}
# Update an index by position
function arr_set() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=
r[]=
}
# Get the array content ${array[@]}
function arr_get() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=
echo ${r[@]}
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_at() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
[[ ! "" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; }
declare -n r=
local max=${#r[@]}
# Array has items and index is in range
if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]]
then
echo ${r[]}
fi
}
# Get the value stored at a specific index eg. ${array[0]}
function arr_count() {
[[ ! "" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; }
declare -p "" > /dev/null 2>&1
[[ $? -eq 1 ]] && { echo "Bash variable [] doesn't exist" 1>&2 ; return 1 ; }
declare -n r=
echo ${#r[@]}
}
array_names=(bob jane dick)
for name in "${array_names[@]}"
do
arr dyn_$name
done
echo "Arrays Created"
declare -a | grep "a dyn_"
# Insert three items per array
for name in "${array_names[@]}"
do
echo "Inserting dyn_$name abc"
arr_insert dyn_$name "abc"
echo "Inserting dyn_$name def"
arr_insert dyn_$name "def"
echo "Inserting dyn_$name ghi"
arr_insert dyn_$name "ghi"
done
for name in "${array_names[@]}"
do
echo "Setting dyn_$name[0]=first"
arr_set dyn_$name 0 "first"
echo "Setting dyn_$name[2]=third"
arr_set dyn_$name 2 "third"
done
declare -a | grep 'a dyn_'
for name in "${array_names[@]}"
do
arr_get dyn_$name
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name by index"
# Print by index
for (( i=0 ; i < $(arr_count dyn_$name) ; i++ ))
do
echo "dyn_$name[$i]: $(arr_at dyn_$name $i)"
done
done
for name in "${array_names[@]}"
do
echo "Dumping dyn_$name"
for n in $(arr_get dyn_$name)
do
echo $n
done
done
For more details on these examples visit Getting Bashed by Dynamic Arrays by Ludvik Jerabek
有关这些示例的更多详细信息,请访问由 Ludvik Jerabek 编写的动态数组
回答by anubhava
Take refuge of eval:
躲避评估:
n=0
for i in aaa bbb ccc; do
eval "array${i}[$n]=$(date "+%N")"
((++n))
done

