pcregrep은 필요한 것보다 한 줄을 더 먹는 여러 줄 정규식을 제외합니다.

pcregrep은 필요한 것보다 한 줄을 더 먹는 여러 줄 정규식을 제외합니다.

바나나 줄로 시작하는 모든 줄 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표현식이 개행 문자를 먹을 수 있다는 것을 의미합니다. 나는 -vpcregrep의 구현에 너무 익숙하지 않아 왜 그 반대가 아닌지 알 수 없지만 그 이유는 확실합니다.

파일을 다음으로 변경하는 경우:

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조건을 부정 하면서 조건과 일치하는 줄을 인쇄합니다.

관련 정보