두 패턴 사이의 출력을 인쇄하고 싶습니다. 첫 번째 패턴은 파일에서 두 번째로 일치해야 합니다.
예 -
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
가 있으면 순서 가 달라집니다).start
start
end
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
첫 번째 시작부터 끝까지 블록을 추출하고 아무 작업도 수행하지 않습니다(passn
). - 그런 다음 처음부터 끝까지 두 번째 블록 인쇄를 수행
/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