테스트 파일은 다음과 같습니다.
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
카운터에 도달하면 종료합니다.c
2
답변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