すべてのパターン発生を最初の一致グループに置き換える

すべてのパターン発生を最初の一致グループに置き換える

ここから始める必要があります。

text match$something_here and match$xxx blablabla
text match$something_else_here and match$xxx blablabla
...

これに関して:

text match$something_here and match$something_here blablabla
text match$something_else_here and match$something_else_here blablabla
...

したがって、ファイルの各行について、xxx2回目以降の内容match$と1回目以降の内容を変更する必要がありますmatch$

答え1

:%s/match\$\zs\(\w\+\)\(.*match\$\)xxx/\1\2\1/

説明する

  • match\$\zs:最初にゲームを固定するmatch$。他のキャプチャグループを避けるために、通常\zsは試合を開始します。
  • \(\w\+\): 最初の発生後のテキストキャプチャmatch$
  • \(.*match\$\):2回目になるまで、次のコンテンツをキャプチャし、match$保持したいコンテンツをキャプチャします。
  • xxx:置き換えられたコンテンツと一致

代替:最初の項目以降のテキスト、その間のテキスト、最初のテキスト(交換xxx)です。

答え2

この試み:

sed -e 's/\(match\$\)\([a-zA-Z_]\+\)\([a-zA-Z ]\+match\$\)[a-zA-Z]\+/\1\2\3\2/' < input.txt > output.txt

input.txt次のいずれかを使用してください。

text match$something_here and match$xxx blablabla
text match$something_else_here and match$xxx blablabla

私は次のようになりますoutput.txt

text match$something_here and match$something_here blablabla
text match$something_else_here and match$something_else_here blablabla

答え3

:%s/\v(match\$(\w+).*match\$)xxx/\1\2/
  • \vは素晴らしいです(\\をより少なく使用できます)

答え4

sed -e 's/\(match\)\([_[:alnum:]]*\)\(\(.*\)\n\)*/\1\
/2;tc' -e b -e :c -e 's//\1\2\4\2/'

上記のシーケンスは、match行にいくつがあるかに関係なく、常に行の最初と2番目の項目のみを処理します。

s///パターンのcdが発生したときに最初の置換を実行し、置換が成功すると連続タグs///2に分岐しtb成功:cbない場合はスクリプトから分岐するように機能します。

したがって、第2の一致に対してパターンが発生した場合、s///2cd代替命令に対してパターンが繰り返される。ただし、そうでない場合、その行は通常どおり印刷されます。

重要なのは\(\(.*\)\n\)*サブ式です。 ewlineは編集の結果としてパターンスペースにのみ表示されるs///2ため、このサブ式は最初のコマンドの空の文字列にのみ一致します。ただし、パターンが繰り返されると、以前の置換が交換時にewlineを挿入したため、2つのesの間に発生するすべての文字が一致します。したがって、同じ繰り返しパターンは、スクリプトのコンテキストに応じて2つの異なる意味を持つことができます。\nsed\(\(.*\)\n\)*matchs///\n[_[:alnum:]]*

上記のバージョンですが、しなければならないすべてのPOSIXに対して作成されたとおりに機能します。sed (強調するしなければならない- 多くのsedsが繰り返しサブ表現基準を満たしていません)、GNUを使用すると、sed短く書くことができます。

sed -E 's/(match)(\w*)((.*)\n)*/\1\n/2;T;s//\1\2\4\2/
' <<\IN
text match_something_here and !m!atch_xxx blablabla
text match_something_here and match_xxx blablabla
text match_something_else_here and match_xxx blablabla
text match_something_here and match_xxx blablabla match_xxx blablabla
text match_something_else_here and match_xxx blablabla match_xxx blablabla match_xxx blablabla
IN

...ビット<<\IN転送は、INここではドキュメントへの入力にすぎないため、どのように機能するかを示すことができます。おそらく<input_fileその場で使用する必要があります。また、私とあなた$somethingとを変更したことに注意してください。$xxxなぜなら、_somethingドル_xxx記号は実際に代替パターンに含まれてはならず、他のものに置き換えられなければならないということです。 true の場合、\w*ord エスケープをそのまま残すことができます。または、文字通りドル記号を含めるには、依然として独自の文字クラスを定義し、次のように追加する必要があります[$_[:alnum:]]*

tc' -e b -e :c -eGNUでは、sedestは1に短縮されますT。ただし、移植可能なestは失敗した行の範囲を超えてt正常に置き換えられますが、GNUではestを使用して失敗した結果を得ることができます。その時点でまだスクリプトを実行している行は、bbsedTした\n行を2番目の一致ペアに正常に置き換えました。

いずれにせよ、(に従ってsed上記の内容のいずれかが印刷されます。

text match_something_here and !m!atch_xxx blablabla
text match_something_here and match_something_here blablabla
text match_something_else_here and match_something_else_here blablabla
text match_something_here and match_something_here blablabla match_xxx blablabla
text match_something_else_here and match_something_else_here blablabla match_xxx blablabla match_xxx blablabla

関連情報