나는 startStr
case 와 사이의 모든 것을 얻으려고 노력하고 있습니다. 나는 사용 방법과 그 사이에 발생하는 모든 이벤트를 이해합니다. 발생 사례를 하나만 제한하는 방법을 모르겠습니다.endStr
bbb
startStr
endStr
sed
bbb
입력 예:
fff
startStr
aaa
bbb
ccc
endStr
xxx
yyy
startStr
ddd
endStr
ddd
bbb
원하는 출력:
startStr
aaa
bbb
ccc
endStr
이것이 내가 가진 것입니다:
$ sed -n -e '/startStr/,/endStr/ p' sample.txt
startStr
aaa
bbb
ccc
endStr
startStr
ddd
endStr
답변1
첫 번째 startStr
... 에 대해 endStr
다음이 포함 /bbb/
됩니다.
sed -n '/startStr/ {:n; N; /endStr/ {/\n[^\n]*bbb[^\n]*\n/ {p; q}; b}; bn}'
또는
sed -n '/startStr/ {:n; N; /endStr/ {/\nbbb\n/ {p; q}; b}; bn}'
정규식이 아닌 경우 bbb
정확히 필요한 문자열입니다(처음부터 까지 \n
).
설명하다
주소의 경우 /startStr/
:
- 라벨 설정
:n
; - 다음 줄 읽기
N
; - 일치하는지 확인하십시오
/endStr/
.- 이것이 사실이라면
/\nbbb\n/
우리가 읽은 이 블록에서 발생을 확인하십시오.- 있는 경우
{p; q}
"인쇄 및 종료"를 수행합니다. - 그렇지 않으면
b
"이 블록을 던지고 다음 블록 검색을 시작하십시오"를 수행하십시오.
- 있는 경우
- 이것이 사실이라면
- 블록의 끝이 아닌 경우 로 이동합니다
:n
. 즉, 계속 읽습니다.
답변2
pcregrep
이 직업에 대한 나의 조언은 다음과 같습니다.
pcregrep -M 'startStr(.|\n)*?bbb(.|\n)*?endStr' sample.txt
옵션을 사용하면 욕심 많은 연산자 없이 -M
여러 줄 패턴을 일치시킬 수 있습니다 . *?
나머지는 분명해야합니다.
답변3
이전에 일치하는 블록 이 startStr...endStr
없는 블록을 포함하도록 입력 샘플을 수정합니다.bbb
$ cat ip.txt
startStr
foo
bar
endStr
fff
baz
startStr
aaa
bbb
ccc
endStr
xxx
yyy
startStr
ddd
endStr
ddd
bbb
awk
해결책
awk '/startStr/{f=1; m=0; buf = $0; next}
/bbb/ && f{m=1}
f{buf = buf ORS $0}
/endStr/ && f{f=0; if(m==1)print buf}
' ip.txt
/startStr/{f=1; m=0; buf = $0; next}
블록 시작을 나타내는 플래그 설정, 일치 항목 지우기, 버퍼 초기화 및 다음 줄로 이동/bbb/ && f{m=1}
행에 가 포함된 경우 일치를 설정합니다bbb
. 외부f
일치를 방지하는 데 사용됩니다 .bbb
startStr...endStr
f{buf = buf ORS $0}
플래그가 설정될 때마다 입력 행을 누적합니다./endStr/ && f{f=0; if(m==1)print buf}
블록 끝에서 일치하는 항목이 발견되면 버퍼를 인쇄합니다.
한 줄로:
$ awk '/startStr/{f=1; m=0; buf = $0; next} /bbb/ && f{m=1} f{buf = buf ORS $0} /endStr/ && f{f=0; if(m==1)print buf}' ip.txt
startStr
aaa
bbb
ccc
endStr
전체 입력 파일을 흡수하여 더 간단한 perl
솔루션 - 유사한 블록이 없다고 가정 startStr...startStr...endStr
(예: first startStr 없음 endStr)
$ perl -0777 -ne '(@m) = /startStr.*?endStr\n/gs; print grep { /bbb/ } @m' ip.txt
startStr
aaa
bbb
ccc
endStr
답변4
sed -n -e '/startStr/,/bbb/p;/bbb/,/endStr/p' /path/to/input