2013-05-13 68 views
0

这里是我的尝试:BASH:如何在一个循环中创建一个动态数组名

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 

任何想法如何使动态数组名工作? 非常感谢!

+0

通常的答案是“不”。你可以使用bash 4的关联数组来创建一个像aaa1''bbb2''ccc3'这样的键的单个数组。 – 2013-05-13 15:25:50

回答

1

采取的EVAL避难所:

n=0 
for i in aaa bbb ccc; do 
    eval "array${i}[$n]=$(date "+%N")" 
    ((++n)) 
done 
+2

使用eval而不使用'printf%q'来创建eval安全的字符串不仅有点冒险。 (是的,在实践中,'date +%N'不可能产生任何不安全的东西......但在实践中,这个答案很可能用于'date'以外的数据。 – 2013-05-13 15:26:47

+0

谢谢,让let和eval都能工作。 现在我的下一个问题是,实际列表包含像“1.1 1.2 mgmt”(接口)这样的项目,格式如下所示。用这样的列表循环被破坏: list = $(echo -e“1.1 1.2 mgmt”) n = 0 for i in $ list;不要让 “array1_ $ I [$ N] = $(日期 ”+%N“)” ((++ n))的 在$列表完成 n = 0的 对于i;做 VAR = array1_ $ I [$ n]的 回声$ {!VAR} ((+ N)) 做 在此先感谢您的任何想法... – 2013-05-14 09:02:57

+0

击(和大多数其他shell)不要”允许在标识符或变量名称中使用'.'s(DOTs),所以即使这样也会失败:'foo1。1 ='bar'' – anubhava 2013-05-14 10:38:42

3

您可以使用间接扩展:

#!/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 

注意,这只会造成数组变量arrayaaa [0]arraybbb [1]arrayccc [2]不是(如你所期望的)arrayaaa [0]arrayaaa [1]arrayaaa [2]arraybbb [0]arraybbb [1]arraybbb [2]arrayccc [0]arrayccc [ 1]arrayccc [2]

+0

+1不使用eval(或者,您可以使用'typeset'而不是'let')。 – 2013-05-13 15:46:45

+0

谢谢,让let和eval都能工作。 现在我的下一个问题是,实际列表包含像“1.1 1.2 mgmt”(接口)这样的项目,格式如下所示。有这样一个列表循环被破坏: list = $(echo -e“1.1 1.2 mgmt”) n = 0 for i in $ list;不要让 “array1_ $ I [$ N] = $(日期 ”+%N“)” ((++ n))的 在$列表完成 n = 0的 对于i;做 VAR = array1_ $ I [$ n]的 回声$ {VAR!} ((+ N)) 做 在此先感谢您的任何想法... – 2013-05-14 09:04:53

+0

@Peter潘:你能编辑你的问题插入这些附加信息?如果给你更好的格式选项。 – 2013-05-14 16:13:17

2

这就是你将如何创建一个动态命名的变量(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[@]} 

下面是一组函数,可用于管理动态命名阵列(版本的bash 4.3 <)。

# Dynamically create an array by name 
function arr() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    # The following line can be replaced with 'declare -ag $1=\(\)' 
    # Note: For some reason when using 'declare -ag $1' without the parentheses will make 'declare -p' fail 
    eval $1=\(\) 
} 

# Insert incrementing by incrementing index eg. array+=(data) 
function arr_insert() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    eval $1[\$\(\(\${#${1}[@]}\)\)]=\$2 
} 

# Update an index by position 
function arr_set() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    eval ${1}[${2}]=\${3} 
} 

# Get the array content ${array[@]} 
function arr_get() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    eval echo \${${1}[@]} 
} 

# Get the value stored at a specific index eg. ${array[0]} 
function arr_at() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    [[ ! "$2" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; } 
    local v=$1 
    local i=$2 
    local max=$(eval echo \${\#${1}[@]}) 
    # 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() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    local v=${1} 
    eval echo \${\#${1}[@]} 
} 



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 

下面是一组可用于管理动态命名数组的函数(bash version> = 4.3)。

# Dynamically create an array by name 
function arr() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -g -a $1=\(\) 
} 

# Insert incrementing by incrementing index eg. array+=(data) 
function arr_insert() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    declare -n r=$1 
    r[${#r[@]}]=$2 
} 

# Update an index by position 
function arr_set() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    declare -n r=$1 
    r[$2]=$3 
} 

# Get the array content ${array[@]} 
function arr_get() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    declare -n r=$1 
    echo ${r[@]} 
} 

# Get the value stored at a specific index eg. ${array[0]} 
function arr_at() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable" 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    [[ ! "$2" =~ ^(0|[-]?[1-9]+[0-9]*)$ ]] && { echo "Array index must be a number" 1>&2 ; return 1 ; } 
    declare -n r=$1 
    local max=${#r[@]} 
    # Array has items and index is in range 
    if [[ $max -gt 0 && $i -ge 0 && $i -lt $max ]] 
    then 
     echo ${r[$2]} 
    fi 
} 

# Get the value stored at a specific index eg. ${array[0]} 
function arr_count() { 
    [[ ! "$1" =~ ^[a-zA-Z_]+[a-zA-Z0-9_]*$ ]] && { echo "Invalid bash variable " 1>&2 ; return 1 ; } 
    declare -p "$1" > /dev/null 2>&1 
    [[ $? -eq 1 ]] && { echo "Bash variable [${1}] doesn't exist" 1>&2 ; return 1 ; } 
    declare -n r=$1 
    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 

有关这些示例的更多细节请访问Getting Bashed by Dynamic Arrays by Ludvik Jerabek