嵌套for循环和变量命名

时间:2016-11-02 18:20:06

标签: bash variables for-loop

我正在尝试使用for循环以下列方式命名我的变量:

for (( a=1; a<=10; a++ )); do
    for (( b=1; b<=100; b++ )); do
        line[$a]position[$b]="This is LINE $a at POSITION $b."
        eval echo "${line[a]position[b]}"
    done
done

这可能,我的代码错了吗?

1 个答案:

答案 0 :(得分:0)

不,这是你尝试的方式不可能的。首先,名称中不允许[](请参阅手册中的definitions),因此您必须使用line${a}position$b之类的名称。

一个(mostly frowned upon)选项是使用eval

#!/bin/bash

for (( a=1; a<=2; a++ )); do
    for (( b=1; b<=2; b++ )); do
        varname=line${a}position$b
        eval $varname=\"This is LINE \$a at POSITION \$b.\"
        echo "${!varname}"
    done
done

首先创建要用作变量名称varname的字符串。对于每个循环,它变为line1position1line1position2等等。

然后,在这一行,我们将您的字符串分配给具有该名称的变量:

eval $varname=\"This is LINE \$a at POSITION \$b.\"

引用是这样的,字符串扩展为,例如第一个循环,

line1position1="This is LINE $a at POSITION $b."

line1position1的值变为This is LINE 1 at POSITION 1.

要访问此变量的值,我们必须使用indirect expansion!中的${!varname}表示varname不是我们想要的变量名称,但< em>扩展到它。

尽管如此,Bash 4.3引入了namerefs,它可以更优雅地解决这个问题:

#!/bin/bash

for (( a=1; a<=2; a++ )); do
    for (( b=1; b<=2; b++ )); do
        declare -n refvar=line${a}position$b
        refvar="This is LINE $a at POSITION $b."
        echo "$refvar"
    done
done

此处不需要eval

两种解决方案的输出都是:

This is LINE 1 at POSITION 1.
This is LINE 1 at POSITION 2.
This is LINE 2 at POSITION 1.
This is LINE 2 at POSITION 2.