1. ホーム
  2. string

[解決済み] sed の置換パターンに対応した文字列をエスケープする

2022-03-14 08:15:20

質問

私のbashスクリプトで、私はsedパターンで使用する必要がある外部(ユーザーから受信した)文字列を持っています。

REPLACE="<funny characters here>"
sed "s/KEYWORD/$REPLACE/g"

をエスケープするにはどうすればよいですか? $REPLACE の文字列が安全に受け入れられるように sed をリテラルに置き換えるのですか?

NOTE KEYWORD は、マッチング等のないダムな部分文字列です。ユーザーから提供されたものではありません。

解決方法は?

警告 : これは ではない は改行を考慮します。より詳細な回答は このSO-question の代わりに (ありがとうございます。 エド・モートン & Niklas Peter)

なお、すべてをエスケープするのは良くない考えです。Sed は多くの文字をエスケープして 得る の特殊な意味を持つ。例えば、置換文字列の中の数字をエスケープすると、後方参照に変わります。

Ben Blankが言ったように、置換文字列でエスケープする必要があるのは3文字だけです(エスケープそのもの、文末のフォワードスラッシュ、すべてを置換する&)。

ESCAPED_REPLACE=$(printf '%s\n' "$REPLACE" | sed -e 's/[\/&]/\\&/g')
# Now you can use ESCAPED_REPLACE in the original sed statement
sed "s/KEYWORD/$ESCAPED_REPLACE/g"

をエスケープする必要がある場合は KEYWORD という文字列が必要です。

sed -e 's/[]\/$*.^[]/\\&/g'

で使用することができる。

KEYWORD="The Keyword You Need";
ESCAPED_KEYWORD=$(printf '%s\n' "$KEYWORD" | sed -e 's/[]\/$*.^[]/\\&/g');

# Now you can use it inside the original sed statement to replace text
sed "s/$ESCAPED_KEYWORD/$ESCAPED_REPLACE/g"

以外の文字を使用した場合は / を区切り文字として使用する場合は、上記の式のスラッシュを、使用する文字に置き換える必要があります。PeterJCLawのコメントで解説しています。

編集しました。 以前は考慮されていなかったいくつかのコーナーケースのために、上記のコマンドは何度か変更されています。詳しくは編集履歴をご覧ください。