テキストファイルでプレースホルダのリストを置き換える方法は?

テキストファイルでプレースホルダのリストを置き換える方法は?

テキスト(構成)ファイルがありますが、残念ながらファイルを読み取るプログラムはいかなる種類の変数も受け入れません。そのため、設定ファイルをプログラムに渡す前に、プリプロセッサを使用して設定ファイルのプレースホルダセットを置き換えたいと思います。

必要に応じて変数の型を定義できます(例§SOME_DIR:)。変数が数個しかない場合は、次のものを使用できますsed

sed  -e "s*§SOME_DIR*$SOME_DIR*g"  my.conf | target_prog

ただし、変数のリストはかなり長く設定が簡単でなければなりません。したがって、変数をプロパティファイルに入れることを好みます。

SOME_DIR=...
OTHER_DIR=...
...

それから電話してください

some_replace_tool  my.properties  my.conf  | target_prog

「some_replace_tool」を探しています。どんなアイデアがありますか?

答え1

出力構成ファイルを生成するためにシェル変数を拡張するスクリプトを作成することもできます。

以下はいくつかのヒントです。

  1. ここでは文字列(<<<)が展開されます。
  2. ".variables.conf"で変数をロードできます。
  3. env -i script.shクリーンな環境でスクリプトを実行します(追加変数なし)。

したがって、スクリプトは変数を取得し、拡張変数を使用してこの文字列を分類する新しい一時スクリプトを作成する必要があります。その後、最終出力を取得するには、一時的に生成されたスクリプトを実行する必要がありますenv -i

答え2

@fredにはいくつかの良いアイデアがありますが、より簡単なシステムは次のとおりです。

sed -ne '/^#/d;s!^\([^=]*\)=\(.*\)$!s@\1@\2g!p' my.proprties > script.sed
sed -f script.sed my.conf | target_prog

また、「PROP = VALUE」の行のみが生成され、コメントアウトされた行は無視されます。

これを分析してみてください。

/^#/d                   - delete any comment lines (to ignore #PROP=VALUE)
s!^\([^=]*\)=\(.*\)$    - match any line with PROP=VALUE and place PROG into group 1 and VALUE into group 2
!s@\1@\2@g              - replace with s@GROUP1@GROUP2@g
!p                      - print the line, to override the -n

次のsedスクリプトが生成されます。

s@PROP1@VALUE1@g
s@PROP2@VALUE2@g
...

答え3

従来のUNIXプリプロセッサと主張できる2つのプリプロセッサがあります。プログラムファイル(Cプリプロセッサ)とm4。どちらもテキストの単語を置き換え、cppの場合はコメント構文を適用するため、一般的な前処理には適していません。合理的な汎用プリプロセッサにはマクロディレクティブがあります(例:が表示されるたびに拡張せずに拡張のみを実行するname@name例:))。

私はどの前処理が事実上の標準であっても普遍的であるとは思わない。さまざまな入力形式で動作し、多くのLinuxディストリビューションで利用可能なツールの1つは次のとおりです。基本計画

標準ツールに固執する場合は、場合によってはシェルをプリプロセッサとして使用できます。文字列を作成して実行

eval 'preprocessed=$(cat <<EOF)
$template
EOF'

シェルパラメータとコマンド($var、、、)が展開されます$(command)`command`テンプレートが外部コマンドを呼び出すか、スクリプトが使用する変数に割り当てることを簡単に防ぐことはできないため、テンプレートソースを信頼しない限り、この機能を使用しないでください。

答え4

アップデート:sed-to-sedのアイデアを拡張すると、インラインであり、中間Arcegeファイルを必要としないfind / replテンプレートのより管理しやすいレイアウト(テーブル形式または非定型)を提供できます。 1行あたりの変更...、などは正規表現として扱われます。gp'<<'EOF'foobarbarsed

I=$'\01'; sed -nre "s/^([^ ]+) +/s$I\1$I/;s/$/$I/p"<<'EOF' |sed -f - file
foo           By the middle of June,
barbar        mosquitos were rampant,
foofoofoo     the grass was tawny, a brown dust
barbarbarbar  haze hung over the valley
EOF

(オリジナルの投稿)
sedラッパーを使用して実行可能なスクリプトとして使用できます。

別のテキストファイルで検索と置換テキストを定義できますが、
この例ではインラインで定義されています。

このスクリプトは find/repl ペアを sed 式に変換し、実行可能なスクリプトを動的に生成します。

I=$'\01'; set -f
printf "#!/bin/sed -f\n" > ~/bin/script.sed
while IFS= read -r line ;do
    ix=$(expr index "$line" " ")
    printf "s%s%s%s%s%s\n" $I ""${line:0:$((ix-1))}"" $I "${line:$ix}" $I 
done <<'EOF' >> ~/bin/script.sed
$text1 By the middle of June,
$text2 mosquitos were rampant,
$text3 the grass was tawny, a brown dust
$text4 haze hung over the valley
EOF
chmod +x ~/bin/script.sed

変更するテストファイルです。
'$'は(sedの場合)行の末尾にはなく、いつでもシェルに公開されないので大丈夫ですが、衝突しないタグは大丈夫ですsed。使用することもできます#

echo '$text1 $text2 $text3 $text4' > file  

$PATH ディレクトリと仮定すると、~/bin実行するコマンドは次のようになります。

script.sed  file   

関連情報