pcregrep excluindo várias linhas regexp consome mais uma linha do que o necessário

1

Eu quero filtrar todas as linhas que começam com banana e todas as linhas que começam com um espaço após as linhas de banana. Eu estou usando pcregrep . Considere o seguinte arquivo fruits.txt :

apple
banana starts matching
 this line should match
 this too
 and this
mango
pomelo

pcregrep felizmente encontra o que eu quero:

ars@ars-thinkpad ~/tmp/tmp $ pcregrep -M  'banana.*\n(\s.*\n)*' fruits.txt 
banana starts matching
 this line should match
 this too
 and this

No entanto, se eu tentar excluir essas linhas, pcregrep também come manga, o que não é bom:

ars@ars-thinkpad ~/tmp/tmp $ pcregrep -M -v 'banana.*\n(\s.*\n)*' fruits.txt 
apple
pomelo

Por quê?

    
por ars 01.08.2017 / 01:02

2 respostas

1

Seu uso de \s na regex significa que a expressão pode incluir novas linhas. Eu não estou familiarizado o suficiente com a forma como o -v é implementado no pcregrep para saber por que não é o inverso, mas tenho certeza que essa é a causa.

Se você alterar seu arquivo para:

apple
banana starts matching
 this line should match
 this too
 and this

mango

pomelo

Então, mesmo sem o -v , a correspondência parece que não é o que você pretende.

$ pcregrep  -M 'banana.*\n(\s.*\n)*' fruits.txt
banana starts matching
 this line should match
 this too
 and this

mango

pomelo

Se for realmente apenas um espaço no início da linha que deve corresponder, sugiro alterar o \s para um ou mais espaços " +" .

Quando eu mudo o regex para 'banana.*\n( +.*\n)*' Ele combina (regular e inverso) de uma maneira que eu acho mais correta. Talvez use [ \t]+ se as guias também forem permitidas.

    
por 01.08.2017 / 04:58
0

Tais tarefas são mais adequadas para awk imo

$ 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
  • O sinalizador de ordem de configuração ajuda a imprimir ou negar facilmente as linhas específicas que estão sendo pesquisadas, pois a condição !/^ / é satisfeita para a linha que começa com banana , bem
  • !/^ /{f=0} se a linha não começar com espaço, limpe o sinalizador
  • /^banana/{f=1} define o sinalizador se a linha começar com banana
  • f imprime a condição de correspondência de linhas, enquanto !f nega a condição
por 01.08.2017 / 06:42