同じファイルに入れ子になった変数を含むファイルから変数を読み取る

同じファイルに入れ子になった変数を含むファイルから変数を読み取る

仲良くして欲しい。

少し混乱しています...

次のファイルがあります。

var1:value1
var2:value2
...
varn:blabla/$var2/blabla

ファイルの読み込みに問題はありません。すべての行を取得し、すべての変数をインスタンス化できます。

簡単に言えば、これが私が関数でやっていることです:

while IFS=":" read -r f1 f2
do
    if [ ! -z $f1 ] && [ ! -z $f2 ]; then

        f2=eval $f2
        export $f1=$f2

    fi
done < $fileName

それ以外はうまくいきますvarn...

わかりました。blabla/$var2/blabla

代わりに:

blabla/value2/blabla...

これはVarnがパスと見なされるので、私のスクリプトはコマンドを開始できません。

実際のパラメータファイルは次のとおりです。

<deleted some parameters>
version:1.7.0

MongoInstall:/apps/deliverable_${version}/mongo

実行中に次のようになります。

+ export 'MongoInstall=/ec/local/nasstat/apps/deliverable_${version}/mongo'
+ MongoInstall='/ec/local/nasstat/apps/deliverable_${version}/mongo'

...

それから...

+ '/apps/deliverable_${version}/mongo/installation_mongo_1.7.0.sh' env stop
./mongotransfer.sh: line 54: /apps/deliverable_${version}/mongo/installation_mongo_1.7.0.sh: No such file or directory

私が得たいものは次のとおりです。

/apps/deliverable_1.7.0/mongo/installation_mongo_1.7.0.sh

ありがとう

答え1

に切り替えるオプションがある場合は、zsh次のことができます。

set -o extendedglob -o nounset
unset MongoInstall
while IFS= read -r line; do
  [[ $line = (#b)([[:IDENT:]]##):(*) ]] &&
    : ${(P)match[1]::=${(e)match[2]}}
done < parameter-file
printf 'MongoInstall="%s"\n' $MongoInstall

そこでコードを楽しく評価するeだけにこのフラグに注意してください。evalたとえば、パラメータファイルにが含まれているとvar=$(reboot)再起動されます。

より安全なアプローチは、拡張を手動で行うことです。

MongoInstall=$(
  perl -wlne '
    if (/^(\w+):(.*)/) {
      $var = $1; $value = $2;
      $value =~ s/\$\{(\w+)\}/$var{$1}/g;
      $var{$var} = $value;
    }
    END {print $var{MongoInstall}}' < parameter-file
)

または次のようになりますzsh

set -o extendedglob -o nounset
typeset -A vars
while IFS= read -r line; do
  if [[ $line = (#b)([[:IDENT:]]##):(*) ]]; then
    var=$match[1] value=$match[2]
    value=${value//(#b)\${([[:IDENT:]]##)}/$vars[$match[1]]}
    vars[$var]=$value
  fi
done < parameter-file
print -r -- $vars[MongoInstall]

ではbash、おそらく次のように書くつもりです。

while IFS=: read -r f1 f2
do
  if [ -n "$f1" ] && [ -n "$f2" ]; then
    eval "$f1=\"$f2\""
  fi
done < parameter-file

仮想行はsをparameter-file含まず、"で終わりません:。通常、$f1有効な変数名または<contents-of-f1>="<contents-of-f2>"有効なコードが含まれていることを確認しようとしません。bash

あなたのコードでは意味がなく、その環境で(引用されていないパーティション+ globに従って)保存されたf2=eval $f2コマンドを実行しようとしています。$f2f2=eval

exportこれらの変数を使用しても、後で実行されるコマンドの環境を汚染する以外には何の効果もありません。

引用符なしでパラメータを拡張することも正しくありませんbash。特に[ -z[ ! -z x ]is [ -n x ]btw)。

関連情報