예를 들어
xyz
A1
B1
C1
D1
End
End
End
X1
X2
X3
Done
xyz부터 끝 패턴까지의 모든 문자열을 추출하고 싶습니다. 그래서 출력은 다음과 같아야합니다
xyz
A1
B1
C1
D1
End
End
End
답변1
방법 1
perl -l -0777ne 'print /^(xyz.*?^End$(?:\nEnd$)*)/ms' yourfile
피복재
- 파일은 하나의 긴 문자열로 나타나도록 읽혀지며, 그런 다음 적절한 정규식을 사용하여 분할될 수 있습니다. 이 예의 정규식은 다음과 같습니다.
- 줄의 시작 부분에서 xyz를 찾습니다(반드시 파일일 필요는 없음).
- 한 줄에서만 가장 가까운 끝을 찾은 다음 가능한 한 많은 연속 줄을 찾습니다.
방법 2
perl -lne '
next unless /xyz/ ... eof;
last if !/End/ and $flag;
$flag ||= 1 if /End/;
print;
' yourfile
피복재
- 여기서는 라인별로 Perl을 작동하고 작은 상태 머신을 설정합니다.
- 파일의 범위가 아닌 부분을 거부합니다.
- 올바른 범위를 입력하면 /End/ 줄에 도달할 때까지 모든 줄을 인쇄합니다. 그때 우리는 표지판을 세웠습니다.
- 그런 다음 /End/가 아닌 첫 번째 줄을 보면 폭발합니다.
방법 3
sed -e '
/xyz/!d
:a
$q;N
/\nEnd$/!ba
:b
n
/End/bb
d
' yourfile
이 방법에서는 /xyz/에서 /End/까지 줄을 누적하는 첫 번째 do-while 루프(:a)를 작동합니다.
두 번째 do-while 루프(:b)는 다음 줄이 /End/가 될 때까지 줄을 인쇄합니다.
방법 4
sed -e '
/xyz/,/End/!d
H;/xyz/h;/End/!d
:a
$q;N
/\(.*\)\n\1$/!{g;q;}
s/.*\n//;H
ba
' yourfile
이 접근 방식을 사용하여 먼저 올바른 범위를 선택한 다음 해당 범위 데이터를 저장 공간에 저장합니다. do-while 루프(:a)는 예약된 공간에 점진적으로 추가되도록 설정되어 있으며 다음 줄은 /End/입니다.
결과
xyz
A1
B1
C1
D1
End
End
End
답변2
이 pcregrep
직업은 다음과 같은 일을 잘합니다:
pcregrep -M 'xyz(.|\n)*End' file
욕심이 많아 끝까지 다 먹지 않으니 주의하세요끝, 기타 포함끝에스.
답변3
Perl이 도움을 줍니다. xyz
첫 번째 줄과 마지막 줄 사이의 모든 줄을 인쇄합니다 End
.
perl -ne '
$inside = 1 if /^xyz$/;
$seen_end = 1 if $inside && /^End$/;
push @buff, $_ if $inside;
print splice @buff if /^End$/ && @buff;
' input-file
첫 번째 발생부터 시작하여 xyz
모든 행을 버퍼로 푸시하기 시작합니다. 일단 End
발생하면 버퍼를 출력하고 지웁니다(참조접합End
), 그러나 나중에 다른 행이 나타날 경우를 대비하여 행을 버퍼에 계속 푸시합니다 .
답변4
앗해결책:
awk '/xyz/,/End/{ print $0; n=NR }($0=="End" && n && NR>n && NR-n++ == 1)' file
산출:
xyz
A1
B1
C1
D1
End
End
End
/xyz/,/End/
- 기록 범위, 에서xyz
까지End
n=NR
- 캡처 레코드 번호(범위 일치 시 - 최종적으로 범위를 포함하게 될 마지막 레코드의 번호)