ここから始める必要があります。
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
...
したがって、ファイルの各行について、xxx
2回目以降の内容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
に分岐しt
、b
成功:c
しb
ない場合はスクリプトから分岐するように機能します。
したがって、第2の一致に対してパターンが発生した場合、s///
2cd代替命令に対してパターンが繰り返される。ただし、そうでない場合、その行は通常どおり印刷されます。
重要なのは\(\(.*\)\n\)*
サブ式です。 ewlineは編集の結果としてパターンスペースにのみ表示されるs///2
ため、このサブ式は最初のコマンドの空の文字列にのみ一致します。ただし、パターンが繰り返されると、以前の置換が交換時にewlineを挿入したため、2つのesの間に発生するすべての文字が一致します。したがって、同じ繰り返しパターンは、スクリプトのコンテキストに応じて2つの異なる意味を持つことができます。\n
sed
\(\(.*\)\n\)*
match
s///
\n
[_[:alnum:]]*
上記のバージョンですが、しなければならないすべてのPOSIXに対して作成されたとおりに機能します。sed
(強調するしなければならない- 多くのsed
sが繰り返しサブ表現基準を満たしていません)、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 -e
GNUでは、sed
estは1に短縮されますT
。ただし、移植可能なestは失敗した行の範囲を超えてt
正常に置き換えられますが、GNUではestを使用して失敗した結果を得ることができます。その時点でまだスクリプトを実行している行は、b
b
sed
T
した\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