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構文です(現在、((i=1;i<=3;i=i+1))andでもサポートされています(andの間にスペースが必要です)。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}(1996年5月以降)、${(P)name}(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また、独自の変数間接指定機能を追加しましたが、ksh93とほぼ反対の意味を持つ別の構文(1996年12月2.0)を使用しました。

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

POSIXシェル(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

出力:

1、2、3

このeval方法では、参照変数の値を取得できます。したがって、変数名自体(上記の「a $ {i}」var、つまりa1、a2など)がある場合は、組み込み関数を介してeval変数の値を取得できます。

以下はいくつかの議論です。Bashの「eval」コマンドは何ですか?

関連情報