简体   繁体   English

嵌套的for循环和变量命名

[英]Nested for-loop and variable naming

I am trying to use a for loop to name my variables in the following manner: 我正在尝试使用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

Is this possible and my code is just wrong? 这可能并且我的代码是错误的吗?

No, this is not possible the way you try it. 不,这是您无法尝试的方式。 First of all, [] are not allowed in names (see definitions in the manual), so you'd have to use a name like line${a}position$b . 首先,名称中不允许使用[] (请参阅手册中的定义 ),因此您必须使用line${a}position$b

One ( mostly frowned upon ) option is to use eval : 一个( 大多数人不赞成 )选项是使用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

This first creates the string to be used as the variable name, varname . 这首先创建用作变量名varname的字符串。 It becomes, for each loop, line1position1 , line1position2 and so on. 对于每个循环,它变为line1position1line1position2等。

Then, on this line, we assign your string to the variable with that name: 然后,在这一行上,将您的字符串分配给具有该名称的变量:

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

The quoting is such that the string expands to, for example for the first loop, 引用是这样的,字符串扩展到例如第一个循环,

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

and the value of line1position1 becomes This is LINE 1 at POSITION 1. . 并且line1position1的值变为This is LINE 1 at POSITION 1.

To access the value of this variable, we have to use indirect expansion : the ! 要访问此变量的值,我们必须使用间接扩展! in ${!varname} indicates that varname is not the variable name we want, but expands to it. ${!varname}表示varname不是我们想要的变量名,而是扩展为它。

This all being said, Bash 4.3 introduced namerefs , which allow to solve this much more elegantly: 总而言之,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

No eval required here. 这里不需要eval

The output for both solutions is this: 这两个解决方案的输出是这样的:

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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM