grep comportamento estranho com palavras de uma única letra

10

Estou removendo as palavras de parada de um texto, usando aproximadamente isso código

Eu tenho o seguinte

$ cat file
file
types
extensions

$ cat stopwords
i
file
types

grep -vwFf stopwords file

Estou esperando o resultado: extensions

mas recebo o (acho incorreto)

file
extensions

É como se a palavra file fosse ignorada no arquivo de palavras irrelevantes. Agora, aqui está a parte legal: se eu modificar o arquivo de palavras irrelevantes, alterando a única palavra / letra i na primeira linha, para qualquer outra letra ascii além de f , i , l , e , então o mesmo comando grep me dá um resultado diferente e correto de extensions .

O que está acontecendo aqui e como eu corrijo isso?

Estou usando o grep (BSD grep) 2.5.1-FreeBSD em um bash GNU do Mac OSX, versão 4.4.12 (1)

    
por Tim 15.10.2017 / 13:33

2 respostas

11

Este foi um bug em bsdgrep , relacionado a uma variável que rastreia a parte da linha atual ainda a ser examinada, que é sobrescrita por chamadas sucessivas ao mecanismo de correspondência de expressões regulares quando vários padrões estão envolvidos.

correção local

Você pode contornar isso até certo ponto, não usando a opção -w , que depende dessa variável para operação correta e, portanto, está falhando, mas usando extensões de expressão regular que correspondem ao início e ao final das palavras, tornando seu arquivo stopwords se parece com:

\<i\>
\<file\>
\<types\>

Esta solução alternativa também exigirá que você não use a opção -F .

Observe que os componentes de expressão regular documentados [[:<:]] e [[:>:]] que o manual re_format informa sobre não funcionam aqui. Isso ocorre porque a biblioteca de expressões regulares que é compilada em bsdgrep tem suporte de compatibilidade de expressão regular do GNU ativado. Este é outro bug, que é declaradamente corrigido.

correção de serviço

Este bug foi corrigido no início deste ano. A correção ainda não chegou aos sabores STABLE ou RELEASE do FreeBSD, mas está em CURRENT.

Para colocar isso na versão MacOS do grep , que é derivado do bsdgrep do FreeBSD, consulte a Apple. ☺

Leitura adicional

por 15.10.2017 / 17:52
2

Este código:

pl " Input data file data1 and stopwords file data2:"
head data1 data2

pl " Expected output:"
cat $E

pl " Results, grep:"
# grep -vwFf stopwords file
grep -vwFf data2 data1

pl " Results, cgrep:"
cgrep -x1 -vFf data2 data1

produz:

-----
 Input data file data1 and stopwords file data2:
==> data1 <==
file
types
extensions

==> data2 <==
i
file
types

-----
 Expected output:
extensions

-----
 Results, grep:
file
extensions

-----
 Results, cgrep:
extensions

Em um sistema como:

OS, ker|rel, machine: Apple/BSD, Darwin 16.7.0, x86_64
Distribution        : macOS 10.12.6 (16G29), Sierra
bash GNU bash 3.2.57

Mais detalhes sobre o cgrep, disponível via brew, e a partir do sourceforge:

cgrep   shows context of matching patterns found in files (man)
Path    : ~/executable/cgrep
Version : 8.15
Type    : Mach-O64-bitexecutablex86_64 ...)
Home    : http://sourceforge.net/projects/cgrep/ (doc)

felicidades, drl

    
por 16.10.2017 / 04:23