bash 動的 (変数) 変数名

bash 動的 (変数) 変数名

要素配列を操作し、いくつかの算術プロセスを生成して文字列シーケンスを動的に生成したいと思います。

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

$6等しい場合、予想される結果は次のとおりです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>}使用してアクセスできます。<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?

素晴らしい!

それ良いecho "${${var3}}"私たちは拡張してecho "${some_variable}"いるCマクロを持っています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}"次のように「良い」バージョン()を読むことができます。

エコーは"$var3"「変数の内容を出力するvar3」という意味です。しかし、echoは次のことを"${!var3}"意味します。 「出力変数にが含まれているとvar3します。その内容はい異なる変数の命名! 」

ここでバッシュ!ほぼ*これらの文字を使用してCでポインタを逆参照するのと同じです! :

*some_ptr

追加抽象化レイヤーを追加します。

関連

  1. !このトリックは通常、次の方法で回避できます。連想配列バッシュから。連想配列は、本質的に 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(強調追加):

    ソート

    バッシュが提供する一次元 索引そして関連配列変数。すべての変数は配列のインデックスとして使用できます。組み込み宣言は配列を明示的に宣言します。配列サイズには最大制限はなく、メンバーを連続的にインデックス付けまたは割り当てる必要もありません。インデックス配列は整数(算術式を含む)を使用して参照され、0から始まります。連想配列は、任意の文字列を使用して参照されます。特に明記しない限り、インデックス配列インデックスは負でない整数でなければなりません。

    name[subscript]=value 構文を使用して変数を割り当てると、インデックス配列が自動的に生成されます。下付き文字は、数値として評価する必要がある算術式として扱われます。インデックス配列を明示的に宣言するには、宣言-a名を使用します(以下のSHELL BUILTINコマンドを参照)。 -a name[subscript] ステートメントも許可されます。

    連想配列は、-A name ステートメントを使用して生成されます。

    宣言と読み取り専用の組み込み関数を使用して、配列変数のプロパティを指定できます。各属性は、配列のすべてのメンバーに適用されます。

    配列は、 name=(value1 ... valuen) 形式の複合割り当てを使用して割り当てられます。ここで、各値は [subscript]=string 形式です。インデックス配列の割り当てには文字列のみが必要です。インデックス配列に割り当てるときにオプションの括弧と下付き文字を指定すると、そのインデックスが割り当てられます。それ以外の場合、割り当てられた要素のインデックスは、ステートメントによって割り当てられた最後のインデックスに1を加えたものです。インデックスは0から始まります。

    連想配列に割り当てるときは、下付き文字が必要です。

答え4

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

これはあなたが試しているものですか?

関連情報