bash動的(変数)変数名


12

要素の配列を操作して、文字列のシーケンスを動的に作成し、算術手続きを作成したい。

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

欲望の結果は、$6equalsの場合以下になり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
それを少し良く説明してもらえますか。何をしようとしているのか本当に理解してはいけません。
ニューロン

`$ name = $(($ 6 + 1))`は何をすべきですか?
PSkocik

@PSkocik私は望んでいたFIRST=$(( $6 + 1 ))
ジャニスクリストファキス

回答:


16

まず=、の変数宣言内にスペースを入れることはできません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

!感嘆符は何のprintf '%s\n' "${!name}"ためですか?
ジャンニスクリストファキス

1
bashパラメーター拡張の間接拡張と呼ばれる
..

1
Bashにはdeclare/ eval:のより良い代替手段もありますprintf -v varname '%fmt' args。一部のbash-completion内部関数は、これを参照渡しに使用します。(保存する変数の名前を渡します)。
ピーターコーデス

注:を使用declareすると、ローカルスコープでのみ変数evalが設定され、アプローチではグローバルに設定されます。
ユーザー

11

名前を別の変数に保存しているときにbash変数を参照する場合は、次のように実行できます。

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

この場合、たとえば、var2にアクセスする変数の名前を保存します。そして、あなたがそれにアクセス${!<varable name>}どこ<variable name>変数がアクセスしたい変数の名前を保持しています。


ポータブルな方法がありますがeval var=\$$holdereval危険です!
ジバンコア

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

それはあなたがしようとしていることですか?


1

コードと目的の出力から得たもの(間違っている場合は修正してください):
"FIRST" / "SECOND" / ...変数名は使用せず、インデックス付きのループが必要です。 。

これは仕事をします:

for i in {1..5} ; do echo $i"q;d" ; done


はい、変数を使用して算術関数を実行したい場合を除き、あなたは正しいです。
ジャンニスクリストファキス

この算術関数の例を教えてください。変数名( "THIRD"など)が必要ですか、それともインデックス値だけですか?
csny

SUM=$(($6 + $i)); echo $SUM"q;d"、私が間違っていたことがわかります。
ジャンニスクリストファキス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.