모든 패턴 발생을 첫 번째 일치 그룹으로 대체

모든 패턴 발생을 첫 번째 일치 그룹으로 대체

여기서부터 시작해야 합니다.

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두 번째 발생 이후의 내용 match$과 첫 번째 발생 이후의 내용을 변경해야 합니다 match$.

답변1

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

설명하다

  • match\$\zs: 처음에 경기 고정 match$; 다른 캡처 그룹을 피하기 위해 보통 \zs그 후에 경기를 시작합니다.
  • \(\w\+\): 첫 번째 발생 이후 텍스트 캡처match$
  • \(.*match\$\): 두 번째 발생할 때까지 뒤에 오는 내용을 캡처 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행에 몇 개가 있는지에 관계없이 항상 행의 첫 번째와 두 번째 항목만 처리합니다.

s///패턴의 cd 발생 시 첫 번째 대체를 수행한 s///2다음 대체가 t성공 하면 연속 태그 b로 분기하고 :c, b성공하지 못하면 스크립트에서 분기하는 방식으로 작동합니다.

따라서 두 번째 일치에 대해 패턴이 발생하면 s///2cd 대체 명령에 대해 패턴이 반복됩니다. 그러나 그렇지 않은 경우 해당 줄은 평소대로 인쇄됩니다.

중요한 것은 \(\(.*\)\n\)*하위 표현식입니다. ewline은 편집 결과로 패턴 공간에만 나타날 수 있기 s///2때문에 이 하위 표현식은 첫 번째 명령의 빈 문자열에만 일치합니다 . 그러나 패턴이 반복되면 이전 교체가 교체 시 ewline을 삽입했기 때문에 두 es 사이에 발생하는 모든 문자가 일치됩니다 . 따라서 동일한 반복 패턴은 스크립트의 컨텍스트에 따라 두 가지 다른 의미를 가질 수 있습니다.\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라인을 두 번째 일치하는 쌍으로 성공적으로 교체했습니다 .

어떤 경우 에라도,(에 따라 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

관련 정보