두 패턴 사이의 문자열을 sed하고 제거합니다.

두 패턴 사이의 문자열을 sed하고 제거합니다.

sed를 사용하여 두 패턴 사이의 문자열 일부를 삭제하는 데 문제가 있습니다. 나는 항상 마지막 PATTERN-2를 정렬합니다.

테스트.txt:

PATTERN-1xxxxPATTERN-2aaa
PATTERN-1xxxxPATTERN-2fffPATTERN-1zzzzPATTERN-2gggPATTERN-1zzzzPATTERN-2
PATTERN-1xxxxPATTERN-2bbb

지침

sed 's/PATTERN-1.*PATTERN-2//g' test.txt

위의 결과는

aaa

bbb

하지만 나는 원한다

aaa
fffggg
bbb

PATTERN-1과 가장 가까운 PATTERN-2를 찾을 수 있나요?

답변1

@steeldriver가 지적했듯이 탐욕스럽지 않은 정규식이 있으면 쉽습니다. 그렇지 않은 경우 다음과 같이 루프를 사용하여 수행할 수 있습니다.

sed ':a;s/PATTERN-2/\n/;s/PATTERN-1.*\n//;ta' test.txt

이는 줄 중간에 개행 문자가 없다는 것을 알고 있기 때문에 작동합니다. 이는 어떤 줄에도 나타나지 않는 다른 문자(예: )에도 적용됩니다 §.

답변2

sed를 사용하고 싶다면 다음을 시도해 보세요

sed 's/PATTERN-1[^P]*PATTERN-2//g' test.txt

답변3

귀하의 예에서 .*는 유지하려는 항목과 일치합니다.

해당 콘텐츠를 캡처하고 다음으로 다시 바꿀 수 있습니다.

sed 's/PATTERN-1\(.*\)PATTERN-2/\1/g' test.txt

대괄호 사이의 모든 내용은 첫 번째 캡처 버퍼에 저장되고 \1해당 버퍼의 값으로 대체됩니다.

답변4

"가장 가까운"은 실제로 sed 용어가 아닙니다. 그러나 시퀀스의 반복 횟수에 합리적인 제한이 있는 경우 PATTERN-1.*PATTERN-2다음과 같이 해당 숫자를 하드코딩할 수 있습니다.

     $ sed -E 's/(PATTERN-1).*(PATTERN-2)(.*)\1.*\2/\3/g;s/PATTERN-1.*PATTERN-2//g' <<"end"
     PATTERN-1xxxxPATTERN-2aaa
     PATTERN-1xxxxPATTERN-2fffPATTERN-1zzzzPATTERN-2gggPATTERN-1zzzzPATTERN-2
     PATTERN-1xxxxPATTERN-2bbb
     end

     aaa
     ggg
     bbb

-E확장 정규식 구문 옵션을 사용한다는 점에 유의하세요 . 또한 검색 표현식에서는 사용자의 편의를 위해 PATTERN-1 및 -2 문자열에 대한 역참조를 사용하고 있습니다.

관련 정보