web-dev-qa-db-ja.com

テキストをパラメータと正規表現に置き換えるための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準拠の方法の拡張機能はありませんか?

6
Emmett Brown

/ onlyをエスケープすることは、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の基本的な正規表現とは対照的に)拡張正規表現であり、置換部分では一致部分を意味すると理解していますが、sedの\1はサポートしていません。 busybox awkを除いて、パターン内の後方参照もサポートしていません。

ここであなたはあなたのアプローチに固執することができますが、/がエスケープされる必要があるという事実を文書化します。とにかく(ユーザーがエスケープする必要があるかもしれないので)どの正規表現演算子であるかを文書化する必要があります。その改行は一致できず、その改行は置換とそこでの&とバックスラッシュの特別な動作でエスケープする必要があります。

8