我想回显 a1,a2,a3 中的值。但我的代码只打印 a1、a2 和 a3,而不打印其中存储的值

我想回显 a1,a2,a3 中的值。但我的代码只打印 a1、a2 和 a3,而不打印其中存储的值
a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1)); do
     echo $a$i
done 

我已经尝试过以下

  1. echo ${a$i}
  2. echo $((ai))
  3. echo ${a}${i}
  4. c=$(echo a$i)

但没有人给出正确答案。

答案1

这是 ksh93 语法(现在也受and((i=1;i<=3;i=i+1))支持(尽管和之间需要空格))。bashzshfor((zsh

ksh93最新版本bash(4.3、2014 或更高版本)中,您可以执行以下操作:

a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1));do
    typeset -n name="a$i"
    printf '%s\n' "$name"
done 

在 中zsh,您可以使用变量间接语法:${(e)code}(since May 1996), ${(P)name}(since 1999)

a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1));do
    name=a$i
    printf '%s\n' "${(P)name}"
    # or
    code="\$a$i"
    printf '%s\n' "${(e)code}"
    # or combined:
    printf '%s\n' "${(e):-\$a$i}" "${(P)${:-a$i}}"
done 

bash还添加了自己的变量间接功能,但使用了不同的语法(1996 年 12 月的 2.0 中),其含义几乎与 ksh93 相反:

a1="one"
a2="two"
a3="three"
for ((i=1;i<=3;i=i+1));do
    name=a$i
    printf '%s\n' "${!name}"
done 

使用任何 POSIX shell(包括但不限于 ksh93、bash 或 zsh),您始终可以执行以下操作:

a1="one"
a2="two"
a3="three"
i=1; while [ "$i" -le 3 ]; do
    name=a$i
    eval "value=\${$name}"
    printf '%s\n' "$value"
    i=$((i + 1))
done 

答案2

在 bash 中,如果您有一个包含所需变量名称的变量,则可以使用间接访问它:

a1="one"
a2="two"
a3="three"
for((i=1;i<=3;i=i+1));do
    name="a$i"
    printf '%s\n' "${!name}"
done 

如果您使用${...}扩展参数,并且第一个字符是,!则其余字符将被视为参数名称,该名称本身包含您要访问的参数名称。

答案3

如果您使用 Bash,完成同样事情的最简单方法是使用数组:

a[1]="one"
a[2]="two"
a[3]="three"

for ((i=1; i<=3; i=i+1)); do
    echo "${a[$i]}"
done

您还可以循环遍历数组:

for value in "${a[@]}"; do
     echo "$value"
done

答案4

如果必须走这条路,那么就进行bash以下工作。这个想法是使用eval

#!/bin/bash

a1="one"
a2="two"
a3="three"

for ((i=1;i<=3;i=i+1)); do
  var="a${i}"
  eval out=\$${var}
  echo $out
done

输出:


二三

eval方法允许获取引用变量的值。因此,一旦我们有了变量名称本身(上面的var“a${i}”,即 a1、a2 等),就可以通过eval内置函数获取变量的值。

这里有一些讨论:bash 中的“eval”命令是什么?

相关内容