bash 动态(变量)变量名

bash 动态(变量)变量名

我想通过操作元素数组并创建一些算术过程来动态创建字符串序列。

for name in FIRST SECOND THIRD FOURTH FIFTH; do
    $name = $(( $6 + 1 ))
    $name = "${$name}q;d"
    echo "${$name}"; printf "\n"
done

$6对于equal来说,期望的结果如下0

1q;d
2q;d
3q;d
4q;d
5q;d

但我收到这个错误

reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution
reel_first_part.sh: line 18: FIRST: command not found
reel_first_part.sh: line 19: ${$name}q;d: bad substitution

我想这很简单。当我做类似的事情时它曾经有效

FIRST=$(( $6 + 1 ))
FIRST="${FIRST}q;d"

答案1

如果您想引用 bash 变量,同时将名称存储在另一个变量中,可以按如下方式执行:

$ var1=hello
$ var2=var1
$ echo ${!var2}
hello

您将要访问的变量的名称存储在本例中的 var2 中。然后您可以使用${!<varable name>}where<variable name>是一个保存要访问的变量名称的变量来访问它。

答案2

首先,=中的变量声明周围不能有任何空格bash

为了得到你想要的,你可以使用eval.

例如像您这样的示例脚本:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    eval "$name"="'$(( $i + 1 ))q;d'"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

印刷 :

1q;d
2q;d
3q;d
4q;d
5q;d

谨慎使用eval,有些人出于某种正当理由称其为邪恶。

declare也会起作用:

#!/bin/bash
i=0
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    declare "$name"="$(( $i + 1 ))q;d"
    printf '%s\n' "${!name}"
    i=$(( $i + 1 ))
done

还打印:

1q;d
2q;d
3q;d
4q;d
5q;d

答案3

我只是想展示一个稍微更彻底的版本埃里克·雷诺夫的回答清楚地说明如何动态生成变量名称多种的其他变量然后访问该新的动态生成变量的内容。

some_variable="Hey how are you?"

# the 1st half of the variable name "some_variable"
var1="some"
# the 2nd half of the variable name
var2="variable"

# dynamically recreate the variable name "some_variable", stored
# as a string inside variable `var3`
var3="${var1}_${var2}"

现在看看这些输出:

echo "${var3}"

输出:

some_variable

但是这个(与上面完全相同除了我们!在变量名之前添加了 char 之外):

echo "${!var3}"

输出:

Hey how are you?

太神奇了!

它是好像我们有一个 C 宏,我们将echo "${${var3}}"其扩展为echo "${some_variable}"然后成为Hey how are you?.

但是,该语法无效,并且您会收到以下错误:

$ echo "${${var3}}"
bash: ${${var3}}: bad substitution

你可以用这个echo "${!var3}"技巧来代替使用eval,因为eval它被认为是“危险的”和“邪恶的”。但为了理解和教育,这是执行此操作的等效eval方法:

$ eval echo "\$${var3}"
Hey how are you?

相对:

$ echo "${!var3}"
Hey how are you?

eval echo "\$${var3}"展开为eval echo "$some_variable",具有相同的输出:

$ eval echo "$some_variable"
Hey how are you?

但是,即使eval echo "\$${var3}"echo "${!var3}"产生完全相同的结果在这种情况下(Hey how are you?输出),显然eval版本是邪恶的,!版本是好的。

您可以阅读“好”版本(echo "${!var3}"),如下(用我自己的话说):

echoing 的"$var3"意思是:“输出变量的内容var3”。但是,回显"${!var3}"意味着:“输出变量包含的内容var3,假设其内容给另一个变量命名!”

这里的bash!有点儿就像在 C 中使用*这样的字符取消引用指针一样!:

*some_ptr

它增加了一个额外的抽象层。

有关的

  1. 请注意,!通常可以使用以下方法来避免使用此技巧关联数组在bash中。关联数组本质上是“哈希表”,在 C++ 中称为“无序映射”,在 Python 中称为“dicts”(字典)。以下是一些相关链接:

    1. https://stackoverflow.com/questions/6149679/multiDimension-associative-arrays-in-bash
    2. [非常好的教程!] *****https://www.artificialworlds.net/blog/2012/10/17/bash-associative-array-examples/

    但请记住,bash 中的关联数组(以及所有其他数组)是一维!来自man 1 bash(强调):

    数组

    Bash 提供一维的 索引联想性的数组变量。任何变量都可以用作索引数组;内置的声明将显式声明一个数组。数组的大小没有最大限制,也没有对成员进行连续索引或分配的要求。索引数组使用整数(包括算术表达式)引用,并且是从零开始的;使用任意字符串引用关联数组。除非另有说明,索引数组索引必须是非负整数。

    如果使用语法 name[下标]=value 分配任何变量,则会自动创建索引数组。下标被视为必须计算为数字的算术表达式。要显式声明索引数组,请使用declare -a name(请参阅下面的SHELL BUILTIN COMMANDS)。声明 -a name[下标] 也被接受;下标被忽略。

    关联数组是使用声明 -A 名称创建的。

    可以使用 declare 和 readonly 内置函数为数组变量指定属性。每个属性适用于数组的所有成员。

    数组使用 name=(value1 ... valuen) 形式的复合赋值进行分配,其中每个值的形式为 [下标]=string。索引数组赋值除了字符串之外不需要任何东西。当分配给索引数组时,如果提供了可选的括号和下标,则该索引被分配给;否则,分配的元素的索引是该语句分配的最后一个索引加一。索引从零开始。

    分配给关联数组时,需要下标。

答案4

index=0;                                                                                                                                                                                                           
for name in FIRST SECOND THIRD FOURTH FIFTH; do
    name=$(($index + 1))
    echo "${name}q;d"
    index=$((index+1))
done

这就是你正在尝试的吗?

相关内容