Sedを使用してファイル内の環境変数を展開する
-
05-07-2019 - |
質問
Sedを使用してファイル内の変数を展開したい。
変数VARIABLE = somethingをエクスポートし、" test"があるとします。次のファイル:
I'd like to expand this: "${VARIABLE}"
次のようなコマンドを試しましたが、役に立ちませんでした:
cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile
結果は" outputfile"です。変数はまだ展開されていません:
I'd like to expand this: "something"
それでも、bashコンソールで eval" echo '$ {VARIABLE}'
を実行すると、値が" something"になります。エコーされています。また、テストを行ったところ、そのパターンは完全に一致しています。
目的の出力は次のようになります
<*>誰でもこれに光を当てることができますか?
解決
試用版を検討してください:
cat test | sed -e "s/\(\${[A-Z]*}\)/`eval "echo '\1'"`/" > outputfile
これが機能しない理由は、シェルの部分に先見性が必要だからです。 sedスクリプトは、sedとパターンが一致する前に生成されるため、シェルはその仕事を実行できません。
これは過去にいくつかの方法で行ってきました。通常、既知の変数とその値のリストがあり、そのリストから置換を行いました。
for var in PATH VARIABLE USERNAME
do
echo 's%${'"$var"'}%'$(eval echo "\$var")'%g'
done > sed.script
cat test | sed -f sed.script > outputfile
変数を任意にマッピングする場合は、環境全体を処理する必要があります(変数名の固定リストの代わりに、適切に編集された env
の出力を使用する)、または代わりにPerlまたはPython。
ご使用のバージョンで環境変数の値にスラッシュが含まれている場合、s ///表記のフィールド区切り文字としてスラッシュを使用すると問題が発生することに注意してください。比較的少数の環境変数がそれを使用しているため、「%」を使用しましたが、一部のマシンで「%」文字を含むものが見つかったため、完全なソリューションはより複雑です。また、値のバックスラッシュについて心配する必要があります。バックスラッシュをエスケープするには、おそらく ' $(eval echo&quot; \ $$ var&quot; | sed' s / [\%] / \\&amp; / g ')
'のようなものを使用する必要があります。環境変数の値のパーセント記号。最後のしわ: sed
の一部のバージョンには、スクリプトサイズの容量が限られています(またはありました)。HP-UXの古いバージョンには、約100の制限がありました。問題ですが、それは5年前と同じくらい最近でした。
元のスクリプトの単純な適応は次のとおりです。
env |
sed 's/=.*//' |
while read var
do
echo 's%${'"$var"'}%'$(eval echo "\$var" | sed 's/[\%]/\\&/g')'%g'
done > sed.script
cat test | sed -f sed.script > outputfile
ただし、より良い解決策は、 env
からの出力に既に値があるという事実を使用するため、次のように記述できます。
env |
sed 's/[\%]/\\&/g;s/\([^=]*\)=\(.*\)/s%${\1}%\2%/' > sed.script
cat test | sed -f sed.script > outputfile
シェルは評価すべきでないものを評価しないため、これは完全に安全です。変数値のシェルメタキャラクターには十分に注意する必要があります。このバージョンでは、 env
からの出力の形式が正しくない場合にのみ問題が発生する可能性があります。
注意- sed
スクリプトを sed
で書くのは難解な作業ですが、優れたツールの力を示すものです。
これらの例はすべて、一時ファイルをクリーンアップしないという点で見過ごされています。
他のヒント
sedを使用せずに取得できる可能性があります:
$ echo $VARIABLE
something
$ cat test
I'd like to expand this: ${VARIABLE}
$ eval "echo \"`cat test`\"" > outputfile
$ cat outputfile
I'd like to expand this: something
シェル変数の補間で作業を行います。