申し訳ありません。とても混乱しています。 (残念です。)
もっと簡単な例を挙げて、もう一度説明します。
#define a new var and export it to the "env":
export VAR_ONE=thisIsVarOne
# check if it was created:
env | grep VAR_ONE #this displays: "VAR_ONE=thisIsVarOne"
# use it in a simple echo command:
echo VAR_ONE=$VAR_ONE #this displays: "VAR_ONE=thisIsVarOne"
# create a new var with the name that contains the value of VAR_ONE ("newvarthisIsVarOne") in its name:
export newvar${VAR_ONE}="somePrefix${VAR_ONE}"
# verify if it has been created:
env | grep newvar # this displays: "newvarthisIsVarOne=somePrefixthisIsVarOne"
今私の質問は次のとおりです。
この新しい複合変数をどのように使用しますか?
注:
env | grep newvar
次の名前のファイルがあることを示します。newvar${VAR_ONE}
しかし、私はできません。住所echo コマンドなどの新しい変数。私は試しましたが、
echo ${newvar${VAR_ONE}}
これは私に与えたbash: ${newvar${VAR_ONE}}: bad substitution
制限要因:
- VAR_ONEの値は変更される可能性があるため、新しく作成された変数を処理するために使用することはできません。
- 静的名では新しい変数を宣言できません。使用するには、スクリプトで
VAR_ONE
新しく生成された変数名の一部としてキーワードが必要です。変数名は次のようにする必要があります。newvar${VAR_ONE}
よろしくお願いします。
答え1
設定:
export VAR_ONE=thisIsVarOne
あなたはbash 4.3+
それを使うことができますnameref
(declare -n
):
$ declare -n _var="newvar${VAR_ONE}" # nameref; define new var name and associate with nameref variable '_var' (can be any valid variable name)
$ _var="somePrefix${VAR_ONE}" # assign value to nameref
$ echo "${!_var}" # show nameref association
newvarthisIsVarOne
$ echo "${_var}" # show value
somePrefixthisIsVarOne
$ echo "${newvarthisIsVarOne}" # explicitly reference new variable by name
somePrefixthisIsVarOne
答え2
設定:
export VAR_ONE=thisIsVarOne
連想配列を使用する代替:
$ unset newvar
$ declare -A newvar
$ newvar[${VAR_ONE}]="somePrefix${VAR_ONE}"
$ typeset -p newvar
declare -A newvar=([thisIsVarOne]="somePrefixthisIsVarOne" )
$ echo "${newvar[${VAR_ONE}]}"
somePrefixthisIsVarOne
コメントでは、OPは、などの複数の変数を参照する必要があることを指摘しましたnewvar${VAR_ONE}
。newvar${OTHER_VAR}
newvar${ANOTHER_VAR}
VAR_ONE
連想配列を使用するこのアプローチは、3つの変数(、、OTHER_VAR
およびANOTHER_VAR
)が異なる値を持つ限り機能します。価値それ以外の場合は、重複した値によって単一の配列エントリが生成されます(最新の割り当ては以前の割り当てを上書きします)。
この3つの変数が同じである場合値別の方法は、リテラルを連想配列のインデックスとして使用することです。たとえば、次のようになります。
#### instead of:
$ newvar[${VAR_ONE}]="somePrefix${VAR_ONE}"
$ typeset -p newvar
declare -A newvar=([thisIsVarOne]="somePrefixthisIsVarOne" )
#### we use:
$ newvar[VAR_ONE]="somePrefix${VAR_ONE}"
$ typeset -p newvar
declare -A newvar=([VAR_ONE]="somePrefixthisIsVarOne" )
答え3
$
bashの変数に影響を与えるためにaを使用しないでください:
var_name=value
var_name1="value with spaces"
var_name2='value with $ or special characters'
変数の値を取得するには、$
名前の前に a を使用します。
echo "var_name=$var_name"
echo "var_name1=use_braces_to_protect_the variable_name_${var_name1}_"
my_new_var="$var_name2"
変数に他の変数の名前が含まれている場合は、変数名の前に感嘆符を付けて中括弧に入れる必要があります。
my_var=spam
the_var_name=my_var
echo "the value is '${!the_var_name}'"
したがって、あなたのプログラムは次のようになります。
#! /bin/bash
VAR1=thisIsVar1
#VAR2=thisIsVar2
VAR3=thisIsVar3
VAR_NAMES=($VAR1 $VAR2 $VAR3)
echo "VAR_NAMES=" "${VAR_NAMES[@]}"
for VAR_NAME in "${VAR_NAMES[@]}"; do
echo
echo "VAR_NAME=$VAR_NAME"
NEW_VAR_NAME="newvar$VAR_NAME"
echo "NEW_VAR_NAME=$NEW_VAR_NAME"
export "${NEW_VAR_NAME}"="somevalue ${VAR_NAME}"
echo "${NEW_VAR_NAME}=${!NEW_VAR_NAME}"
done
修正する
新しいvar_name / var_valueをキー/値として使用して、ハッシュテーブル(関連配列)を作成することもできます。
#! /bin/bash
VAR1=thisIsVar1
#VAR2=thisIsVar2
VAR3=thisIsVar3
VAR_NAMES=($VAR1 $VAR2 $VAR3)
echo "VAR_NAMES=" "${VAR_NAMES[@]}"
declare -A NEW_VAR_NAMES=()
for VAR_NAME in "${VAR_NAMES[@]}"; do
echo
echo "VAR_NAME=$VAR_NAME"
NEW_VAR_NAME="newvar$VAR_NAME"
echo "NEW_VAR_NAME=$NEW_VAR_NAME"
export "${NEW_VAR_NAME}"="somevalue ${VAR_NAME}"
echo "${NEW_VAR_NAME}=${!NEW_VAR_NAME}"
NEW_VAR_NAMES+=(["${NEW_VAR_NAME}"]=${!NEW_VAR_NAME})
done
echo
echo "${NEW_VAR_NAMES[@]@A}"
for new_var_name in "${!NEW_VAR_NAMES[@]}"; do
echo "new_var_name is ${new_var_name} and its content is '${NEW_VAR_NAMES[$new_var_name]}'"
done
答え4
訪問するシェル別の変数(${!pointer}
構文または名前参照用)を使用する代わりに変数を使用する唯一の解決策は、を使用するeval
ことです。
eval "echo \$newvar$VAR_ONE"
— しかし間違いをすると危険であり、事実上すべての人間が間違いをします。
しかし、~のため環境変える作成したら、export
サブプロセスを使用して照会を実行できます。特にawk
一般的に現れるPOSIXは最大システムには以下が含まれますbash
。
awk -v name=newvar$VAR_ONE 'BEGIN{printf "%s",ENVIRON[name]}'
# or simpler {print ENVIRON[name]} adds newline which may be okay,
# e.g. if you use this in $(...) or `...` which removes newline
# or _instead of_ an echo command because echo also adds newline
はるかにシンプルで多くのシステムがあり、printenv
これを行うことができますprintenv newvar$VAR_ONE
。これにより、改行文字も追加されます。