したがって、いくつかの変数を定義するためにプロパティファイルをロードします。この例では、mark!slash\ending\
名前が文字列であると想定していますINPUT
。
INPUT
以下を使用してプロパティファイルをロードして宣言します。
. ./properties
どこ
INPUT=mark!slash\ending\
最終出力はSEDを介して実行されるスクリプトでなければなりません。s!@output@!$INPUT!g
これにより、実行時に@output@
カスタム属性ファイルの入力が他のファイル(この場合は変数INPUT
)に置き換えられます。 SEDは区切り文字を使用するため、!
SEDテンプレートファイルに追加する前にこの文字(およびすべての文字)をエスケープする必要があります。\
試してみると
echo SAFE_INPUT=$(printf '%s\n' 'mark!slash\ending\' | sed 's:[\!]:\\&:g')
期待した結果を得ました。
mark\!slash\\ending\\
しかし、私が試してみると
SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
わかりました。
mark\!slashending
私はこれが文字列対変数の宣言に関連していると仮定していますが、今は違いと問題を解決する方法がわかりません。
編集:追加テストにINPUT
使用
. ./properties
次に印刷
mark!slashending
したがって、これはSEDの問題ではなく、プロパティファイルの読み込みに問題があることです。
答え1
問題は、質問に示すようにINPUT
ファイルに変数を設定するときです。properties
INPUT=mark!slash\ending\
シェルスクリプトで入手してください。
最初の行の後にスペースがある場合は、行の末尾の\e
シェルに置き換えe
られます。それ以外の場合、行は次の行に続くことを意味します。\
だから値がINPUT
修正されました。
引用符で入力を定義する必要があります。
INPUT='mark!slash\ending\'
properties
Cornholioの答えのようにそうでない場合は、ファイルを別々に解析する必要があります。
次のコマンドを使用すると、INPUT変数(およびに追加の行がある場合は他の変数properties
)を正しい値に設定します。
eval $(sed -e 's:[\!]:\\&:g' properties)
これにより、 および の内容を置き換えるeval
uate コマンドの出力がシェルに提供されます。結果は元の名前などを持つ変数になります。ファイルに1つ以上の変数割り当てが含まれている場合に機能します。他のシェルスクリプトコードの場合、奇妙な結果が表示されることがあります。sed
\
!
properties
INPUT
properties
メモ:入力ファイルに他の特殊文字が含まれていると、処理が難しくなります。したがって、別途の確認なしに使用することはeval
脆弱または危険な場合があります。
あなたの例によると、変数はINPUT
期待値を持っています。mark!slash\ending\
その後はできます
SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
SAVE_INPUT
含める変数が必要な場合mark\!slash\\ending\\
。
より良いアプローチは、入力を1行ずつ読み込み、行を調べて処理while read -r line
して変数名と値を分離することです。
答え2
引用された値で以下を実行するとINPUT
機能します。
> INPUT='mark!slash\ending\'
> SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
> echo $SAFE_INPUT
mark\!slash\\ending\\
INPUT=
これは私が追加したものを含むスクリプトの正確なコピーです。