패턴 1과 패턴 2의 두 번째 일치 사이의 선을 어떻게 인쇄합니까?

패턴 1과 패턴 2의 두 번째 일치 사이의 선을 어떻게 인쇄합니까?

테스트 파일은 다음과 같습니다.

PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2
g
h

PATTERN1두 번째 일치 항목 사이의 줄을 인쇄하고 싶습니다 PATTERN2.

PATTERN1
a
b
c
PATTERN2
d
e
f
PATTERN2

답변1

한 가지 방법은 다음과 같습니다 sed.

sed '/PATTERN1/,$!d;/PATTERN2/{x;//{x;q;};g;}' infile

이는 첫 번째 발생(있는 경우) 이전의 모든 행을 삭제한 PATTERN1다음 PATTERN2일치하는 모든 행의 버퍼를 변경합니다 x. 새 패턴 공간도 일치하는 경우 이는 두 번째 발생이라는 의미이므로 x원래의 상태 q(자동 인쇄 후)로 다시 변경됩니다. 일치하지 않으면 첫 번째 발생이라는 의미이므로 패턴 공간을 통해 예약 공간 콘텐츠를 복사하고 g(이제 예약 버퍼에 일치하는 라인이 있음 PATTERN2) 계속됩니다...
다른 방법이 있습니다 awk.

awk '/PATTERN1/{t=1}; t==1{print; if (/PATTERN2/){c++}}; c==2{exit}' infile

PATTERN2일치하는 줄을 만날 때만 인쇄를 시작하고 일치하는 줄 수를 계산하고, PATTERN1카운터에 도달하면 종료합니다.c2

답변2

작업에 적합한 도구는 다음과 같습니다 pcregrep.

pcregrep -M 'PATTERN1(.|\n)*PATTERN2' file

where 옵션을 -M사용하면 패턴이 여러 줄과 일치하고 (.|\n)*모든 문자 또는 개행 문자와 0번 이상 일치할 수 있습니다.

우리는 grep의 탐욕스러운 특성을 이용하고 있습니다. 테이블 패턴1을 인쇄하려면첫 번째Pattern2가 나타나면 *?대신 non-greedy를 사용해야 합니다 *.

n일반화하여 PATTERN2의 첫 번째 발생 까지 인쇄하려면 다음을 수행하십시오 .

pcregrep -M 'PATTERN1((.|\n)*?PATTERN2){n}' file

n필요한 실제 숫자로 변경하십시오 .

답변3

그냥 플래그를 사용하세요:

$ awk '/PATTERN1/{flag=2;next} flag; /PATTERN2/{flag--}' file
a
b
c
PATTERN2
d
e
f
PATTERN2

즉, PATTERN1플래그를 양수 값으로 설정하는 경우입니다. 그런 다음 그것을 찾으면 PATTERN2해당 플래그를 1씩 줄입니다. 이렇게 하면 두 번째 게임 후에는 고갈됩니다. 그 사이에 flag참값(2 또는 1)이 있을 때 트리거되는 값으로 사용됩니다.{print $0}

답변4

sed필요한 라인을 쉽게 수집한 다음 인쇄할 수 있다고 말하면

sed -n '
    /PATTERN1/{
        :1
        $!N
        /\(PATTERN2\).*\1/!b1
        p
    }
' file

관련 정보