4

私の問題は、シェルスクリプトと同様の問題です。小さな例外を除いて、複数の行を検索して置換します。

リンクされた質問では、ユーザーはこれを行いたいと考えています:

source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [stuff here, possibly multiple lines.
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
[stuff after]

私の問題は似ています、私はこれをしたいです:

source:
[stuff before]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [this]
<!--WIERD_SPECIAL_COMMENT_END-->
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [not this]
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]    

target:
[stuff before]
[new content]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [not this]
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]

適切な複数行の正規表現では、これは簡単に行うことができます:

/<!--WIERD_SPECIAL_COMMENT_BEGIN-->.*[this].*<!--WIERD_SPECIAL_COMMENT_END-->/m

しかし、リンクされた質問で提案されている答えは、範囲として正規表現を使用しているため、2 つの範囲外の境界の間の行をチェックできません。

一度にすべての行を正規表現できるように、範囲内のすべての行をパターン バッファに追加する方法はありますか? 例えば:

sed '
    #range between comment beginning and comment end
    /<!--WIERD_SPECIAL_COMMENT_BEGIN-->/,/<!--WIERD_SPECIAL_COMMENT_END-->/
    #Do something to add the lines in this range to pattern buffer
    /.*[this].*/d
    #Delete all the lines if [this] is in the pattern buffer
' <in.txt >out.txt
4

5 に答える 5

3

Perl では、比較的単純です。

perl -0777pe 's/<!--BEGIN-->\n(?:(?!<!--END-->\n).)*?\[this\].*?\n<!--END-->\n/[new content]\n/s' in.txt

Perl によって提供される利点は次のとおり-0777ですsed。(b)/sドットが改行に一致することを可能にする正規表現フラグ。(c) けちな繰り返し演算子*?とその仲間。これにより、繰り返しが可能な限り一致するのではなく、可能な限り一致しなくなります。最後に (d)(?!...)否定先読み式が一致する場所での一致を禁止できる否定先読み。sed(これがなければ、"stuff before" テキストに "false" の開始区切り文字があれば、けちなマッチングでも終了区切り文字を越えて一致します。) ... そしてもちろん、(e)だけの汎用プログラミング言語比較的単純なテキスト処理タスクに適しています。

(私はより単純な開始と終了の区切り文字を使用しました。「wierd」が意図的なスペルミスであることを願っています。)

于 2012-07-29T16:29:49.497 に答える
0

範囲内のすべての行をパターンバッファーに追加して、すべての行を一度に正規表現できるようにする方法はありますか?

確かに、ホールドスペースを使用してください。例えば:

sed -n '/begin/,/end/{ /begin/{h;d};H}; /end/{g;s/\n/<newline>/gp}'

'begin'と'end'に一致する行間の改行をテキストに置き換えます<newline>

于 2012-07-27T16:35:06.557 に答える
0

免責事項:私は初心者です。これは確かに最善の方法ではありません。


私は3つのステップで似たようなことをしました。Linux で実行していると仮定すると、次のことができます。

1) ファイル内のすべての改行を特殊文字に置き換えます。

cat originalText.txt | tr '\n' '~' > temp

2)お気に入りの方法(私はperlを使用)を使用して正規表現を実行し、改行が必要な各位置に特殊文字のインスタンスを配置します。特殊な改行文字はそのままにしておいてください。

3) 今回は最初のコマンドを逆に実行します。

cat temp | tr '~' '\n' > modText.txt

これが役立つことを願っています。

于 2012-07-27T15:56:26.313 に答える
0

これはうまくいくかもしれません(GNU sed):

sed ':a;$!N;/^<!--WIERD_SPECIAL_COMMENT_BEGIN-->/!{P;D};/<!--WIERD_SPECIAL_COMMENT_END-->$/!ba;s/\[this\]/[new content]/;p;d' file
于 2012-07-28T06:31:44.780 に答える
-1

あなたは次のようにそれを行うことができますsed

parse.sed

/BEGIN/ {               # If we encounter BEGIN
  :a                    # Read all until END
  N                     # into pattern space
  /END/!ba              # /
  /\[this\]/d           # If the block contains [this], delete it
  s/^/[new content]\n/  # Insert [new content] before the block
}

次のように実行します。

sed -f parse.sed infile

出力:

[stuff before]
[new content]
<!--WIERD_SPECIAL_COMMENT_BEGIN-->
  [not this]
<!--WIERD_SPECIAL_COMMENT_END-->
[stuff after]
于 2012-07-27T15:47:07.043 に答える