돈의 더 나은 대부분의 경우에있을 수 있습니다,하지만 단지의 경우 파일은 정말 큰, 당신이 얻을 수없는 sed많은 것을 스크립트 파일 처리 (스크립트의 약 5000 라인에서 일어날 수있는)을 , 여기에 일반에이다 sed:
sed -ne:t -e"/\n.*$match/D" \
-e'$!N;//D;/'"$match/{" \
-e"s/\n/&/$A;t" \
-e'$q;bt' -e\} \
-e's/\n/&/'"$B;tP" \
-e'$!bt' -e:P -e'P;D'
이것은 입력시 슬라이딩 윈도우 라고 불리는 것의 예입니다 . 미리보기 버퍼를 구축하여 작동합니다.$B인쇄하기 전에 -count 라인 .
그리고 실제로, 나는 아마도 이전의 요점을 분명히해야합니다 :이 솔루션과하지 않는 것에 대한 주요 성능 제한 기는 간격과 직접 관련이 있습니다. 이 솔루션은 더 큰 간격 크기로 느리게 진행 되는 반면 더 큰 간격 주파수로 느리게 진행 . 다시 말해서, 입력 파일이 매우 큰 경우에도 실제 간격 발생이 여전히 매우 드물다면 그의 해결책이 나올 것입니다. 그러나 간격 크기를 상대적으로 관리 할 수 있고 자주 발생할 수있는 경우이 방법을 선택해야합니다.
워크 플로는 다음과 같습니다.
- 경우
$match앞에는 패턴 공간에서 발견된다 \newline, sed재귀합니다 D모든 elete \newline 그 선행을.
- 나는 정리하고 있었다
$match 전에 패턴 공간을 완전히 있었지만 겹치기를 쉽게 처리하면 랜드 마크를 남기는 것이 훨씬 잘 작동하는 것 같습니다.
- 나는 또한 시도
s/.*\n.*\($match\)/\1/하나 가서 루프를 피할 그것을 얻기 위해 노력하지만, 때 $A/$B큰의 Delete 루프는 상당히 빠른 증명한다.
- 그런 다음 ewline 구분 기호가
N앞에 오는 입력 의 ext 행 \n을 D가져 와서 /\n.*$match/가장 최근에 사용한 정규 표현식 w /을 참조하여 다시 한 번 다시 시도하십시오 //.
- 패턴 공간이 일치 하면 라인의 헤드
$match에서만 가능합니다. $match모든 $Before 라인이 지워졌습니다.
- 그래서 우리는
$After를 반복하기 시작 합니다.
- 이 루프의 각 실행 우리는에 시도 할 수 있습니다
s///에 대한 ubstitute &자체 $A번째 \n패턴 공간에서 ewline 문자를하고, 성공하면, t우리의 전체와 - 동부 표준시 우리를 분기 것이다 $A완전히 정상에서 위로 스크립트를 시작하는 스크립트 밖으로 - 따고 버퍼 다음 입력 라인이있는 경우
- 는 IF
t추정이 성공하지 우리는거야 b받는 목장 다시 :t입력의 또 다른 라인에 대한 연산 레이블과 같이 Recurse - 가능하면 이상 루프 시작 $match수집하는 동안 발생 $A따고가.
- 우리가 과거를 얻을 경우
$match기능 루프, 우리는하려고합니다 pRINT $경우이 그것을 경우 마지막 줄을, 그리고 !시도하지 s///에 대한 ubstitute &자체 $B번째 \n패턴 공간에서 ewline 문자.
- 우리도 이것을 할 것이고
t, 성공하면 :Print 라벨로 분기 할 것 입니다.
- 그렇지 않으면
:top로 다시 분기 하여 버퍼에 추가 된 다른 입력 라인을 얻습니다.
- 우리가 만드는 경우는 다음의 제품에
:P우리가 있습니다 RINT P다음 RINT D첫까지 elete \n패턴 공간에서 ewline와 남아있는 것과 상단에서 스크립트를 다시 실행하십시오.
이번에는 우리가하고 있다면 A=2 B=2 match=5; seq 5 | sed...
:Print 에서 첫 번째 반복을위한 패턴 공간 은 다음과 같습니다.
^1\n2\n3$
그리고 그것이 efore 버퍼를 sed모으는 방법 $B입니다. 그리고 수집 된 입력 뒤에sed 출력 $B카운트 라인을 인쇄합니다 . 앞의 예를 주어,이 수단은 것 RINT 출력 한 다음 elete 그와 스크립트의 상단에 같이있는 모습 패턴 공간을 다시 보내 :sedP1D
^2\n3$
... 그리고 스크립트 상단에서 Next 입력 라인이 검색되므로 다음 반복은 다음과 같습니다.
^2\n3\n4$
5입력에서 처음 나타나는 것을 발견 하면 패턴 공간은 실제로 다음과 같습니다.
^3\n4\n5$
그런 다음 Delete 루프가 시작되고 통과하면 다음과 같습니다.
^5$
그리고 Next 입력 라인을 당기면 sedEOF를 누르고 종료합니다. 그때 P까지는 라인 1과 라인 2 만 헹 구었습니다.
다음은 예제 실행입니다.
A=8 B=7 match='[24689]0'
seq 100 |
sed -ne:t -e"/\n.*$match/D" \
-e'$!N;//D;/'"$match/{" \
-e"s/\n/&/$A;t" \
-e'$q;bt' -e\} \
-e's/\n/&/'"$B;tP" \
-e'$!bt' -e:P -e'P;D'
인쇄 :
1
2
3
4
5
6
7
8
9
10
11
12
29
30
31
32
49
50
51
52
69
70
71
72
99
100