첫 번째 패턴이 두 번째로 나타나는 경우에만 두 패턴 사이에 인쇄

첫 번째 패턴이 두 번째로 나타나는 경우에만 두 패턴 사이에 인쇄

두 패턴 사이의 출력을 인쇄하고 싶습니다. 첫 번째 패턴은 파일에서 두 번째로 일치해야 합니다.

예 -

test.txt

start one
text_1   
end
start two
text_2
end 
start three
text_3
end

여기서 첫 번째 모드는 start이고 두 번째 모드는 입니다 end. 패턴은 start파일에서 두 번째 패턴 일치여야 합니다. 그런 다음 출력은 다음과 같아야합니다

start two
text_2
end

답변1

다음을 사용하여 n번째 레코드awk 로 쉽게 확장할 수 있습니다 .

awk '/start/ && ++n == 2, /end/' < file

start두 번째 발생부터 첫 번째 발생까지 줄을 인쇄합니다 end.

두 번째 start레코드를 인쇄합니다( , end가 있으면 순서 가 달라집니다).startstartend

awk '
  /start/, /end/ {
    if (!seen) {seen = 1; n++}
    if (n == 2) print
    if (/end/) seen = 0
  }' < file

또는:

awk '
  !inside && /start/ {inside = 1; n++}
  !inside {next}
  n == 2
  /end/ {inside = 0}' < file 

답변2

그리고sed

sed -n '/start/,/end/n;/start/,/end/{p;/end/q}' file

설명하다:

  • -n출력 억제
  • 먼저 /start/,/end/n첫 번째 시작부터 끝까지 블록을 추출하고 아무 작업도 수행하지 않습니다(pass n).
  • 그런 다음 처음부터 끝까지 두 번째 블록 인쇄를 수행 /start/,/end/하고 끝에 도달하자마자 종료합니다.p;/end/q

답변3

이 특별한 경우 - 입력이 /start/,/end/블록으로만 구성된 경우 간단히 다음을 수행할 수 있습니다.

sed '1,/end/d;//q' infile

이 블록 사이에 다른 줄이 있는 경우(일치 없음 end)

sed '1,/end/d;/start/,/end/!d;/end/q' infile

보다 일반적인 경우, 추출할 청크가 n하나인 경우 다음을 실행할 수 있습니다.

n=5
awk  -vc=$n '/start/{i++};{if (i==c){print;if (/end/){exit}}}' infile

답변4

sed -ne '
   /^start/,/^end/!d; # skip non-interesting block
   /^start/H;         # increment hold counter
   G;/\n.*\n.*\n/!d;  # check if 2nd block reached?
   P;/^end/q;         # we"re in 2nd block so print & quit on /end/
' yourfile

perl -l -0777ne 'print+(/^start.*?\nend[^\n]*$/msg)[1]' yourfile

관련 정보