テキストを引数と正規表現に置き換えるposix互換関数

テキストを引数と正規表現に置き換えるposix互換関数

文字を挿入する可能性がなく、正規表現の使用を放棄せずに安全な方法で正規表現を使用して文字列を置き換える関数を作成しています。

#! /bin/sh

stringer()
{
    pattern="${1}"
    replace="${2}"

    printf '%s\n' "examp/e w\\th sed: " | sed "s/${pattern}/${replace}/g"
}

stringer "\\/" "l"

これまでは大丈夫でしたが、次のものを使用した場合:

stringer "/" "l"

sed エラーが発生します。これに関しては、入力パラメータをエスケープできることを知っていますが、正規表現では機能しません。正規表現で使用できるようにしたい。 sedの有無にかかわらず提案はありますが、Posixはありません。互換拡張?

答え1

sedたとえば、次から脱出する必要があるため、/を脱出するのは非常に困難です。

Foo/bar
Foo[XY]/
Foo\[/x\]
Foo\\/bar

しかし、中にはありません。

Foo [/x]bar
Foo [^]/x]bar
Foo [x[:blank:]/y]
Foo\/bar

awk使いやすくなるかもしれません。

repl() {
  PATTERN=$1 REPL=$2 awk '
    {gsub(ENVIRON["PATTERN"], ENVIRON["REPL"]); print}'
}

ただし、awkの正規表現は拡張正規表現です(sedの基本正規表現とは対照的に)。一致する部分を示すために置換部分の & を理解しますが\1busybox awk を除けば、またスキーマの逆参照もサポートしません。

ここでは、アプローチに固執しながら/をエスケープする必要があるという事実を記録できます。それにもかかわらず、正規表現演算子が何であるかを文書化する必要があり(ユーザーがこれをエスケープする必要があるため)、改行文字は一致せず、代替項目とバックスラッシュの特殊動作で改行文字をエスケープする必要があります。

関連情報