바나나 줄로 시작하는 모든 줄 banana
과 바나나 줄 뒤에 공백으로 시작하는 모든 줄을 필터링하고 싶습니다. 을 사용하고 있습니다 pcregrep
. 다음 파일을 고려하십시오 fruits.txt
.
apple
banana starts matching
this line should match
this too
and this
mango
pomelo
pcregrep
내가 찾던 것을 발견하게 되어 기쁩니다:
ars@ars-thinkpad ~/tmp/tmp $ pcregrep -M 'banana.*\n(\s.*\n)*' fruits.txt
banana starts matching
this line should match
this too
and this
그런데 이 대사를 제외하려고 하면 pcregrep
망고도 먹게 되어 좋지 않습니다.
ars@ars-thinkpad ~/tmp/tmp $ pcregrep -M -v 'banana.*\n(\s.*\n)*' fruits.txt
apple
pomelo
왜?
답변1
정규 표현식에서 사용하는 것은 \s
표현식이 개행 문자를 먹을 수 있다는 것을 의미합니다. 나는 -v
pcregrep의 구현에 너무 익숙하지 않아 왜 그 반대가 아닌지 알 수 없지만 그 이유는 확실합니다.
파일을 다음으로 변경하는 경우:
apple
banana starts matching
this line should match
this too
and this
mango
pomelo
그렇지 않더라도 -v
경기가 원하는 대로 보이지 않습니다.
$ pcregrep -M 'banana.*\n(\s.*\n)*' fruits.txt
banana starts matching
this line should match
this too
and this
mango
pomelo
일치해야 할 줄 시작 부분에 실제로 공백이 하나만 있는 경우 공백 \s
을 하나 이상으로 변경하는 " +"
.
정규식을 'banana.*\n( +.*\n)*'
It으로 변경하면 더 정확하다고 생각되는 방식(정규 및 역방향)으로 일치합니다. [ \t]+
탭도 허용하면 작동할 수도 있습니다.
답변2
awk
내 생각에는 그러한 작업이 더 적합하다고 생각됩니다
$ awk '!/^ /{f=0} /^banana/{f=1} f' fruits.txt
banana starts matching
this line should match
this too
and this
$ awk '!/^ /{f=0} /^banana/{f=1} !f' fruits.txt
apple
mango
pomelo
- 플래그가 설정된 순서는 다음
!/^ /
으로 시작하는 줄에 대해서도 조건이 충족 되므로 검색 중인 특정 줄을 쉽게 인쇄하거나 부정하는 데 도움이 됩니다.banana
!/^ /{f=0}
줄이 공백으로 시작하지 않으면 플래그를 지웁니다./^banana/{f=1}
줄이 다음으로 시작하는 경우 플래그 설정banana
f
!f
조건을 부정 하면서 조건과 일치하는 줄을 인쇄합니다.