grep comportamiento extraño con palabras de una sola letra

10

Estoy eliminando palabras vacías de un texto, aproximadamente usando este código

Tengo lo siguiente

$ cat file
file
types
extensions

$ cat stopwords
i
file
types

grep -vwFf stopwords file

Estoy esperando el resultado: extensions

pero me sale el (creo que incorrecto)

file
extensions

Es como si la palabra filese hubiera omitido en el archivo de palabras clave. Ahora aquí está la parte fría: si modifica el archivo de palabras vacías, cambiando la palabra / carta ien la primera línea, a cualquier otra letra ASCII, aparte de f, i, l, e, a continuación, el mismo comando grep me da un resultado diferente y correcta de extensions.

¿Qué está pasando aquí y cómo lo soluciono?

Estoy usando grep (BSD grep) 2.5.1-FreeBSD en un Mac OSX GNU bash, versión 4.4.12 (1)

Tim
fuente
¿Es posible que desee utilizar el -xinterruptor para regex de línea en lugar de -wpara word? Sin embargo, creo que el -Finterruptor cancelará cualquiera de ellos, o viceversa.
jesse_b
grep (GNU grep) 3.1 funciona como espera.
Hauke ​​Laging
He replicado esto. Otro dato: Convertir el ipatrón en el segundo patrón en lugar del primer patrón en el stopwordsarchivo también altera el comportamiento.
JdeBP
No puedo reproducir el comportamiento en OpenBSD 6.2 con Native grepni con GNU grep3.1.
Kusalananda

Respuestas:

13

Este fue un error bsdgreprelacionado con una variable que rastrea la parte de la línea actual que aún se escanea y que se sobrescribe con llamadas sucesivas al motor de coincidencia de expresiones regulares cuando hay varios patrones involucrados.

arreglo local

Puede evitar esto hasta cierto punto si no utiliza la -wopción, que se basa en esta variable para el funcionamiento correcto y, por lo tanto, falla, sino que usa las extensiones de expresión regular que coinciden con el principio y el final de las palabras, haciendo que su stopwordsarchivo se vea así:

\ <i \>
\ <archivo \>
\ <tipos \>

Esta solución también requerirá que no use la -Fopción.

Tenga en cuenta que los componentes de expresión regular documentados[[:<:]] y [[:>:]]que el re_formatmanual le informa no funcionarán aquí. Esto se debe a que la biblioteca de expresiones regulares que se compila bsdgreptiene la compatibilidad de compatibilidad de expresiones regulares GNU activada. Este es otro error, que, según los informes, se ha solucionado.

servicio fijo

Este error se solucionó a principios de este año. La solución aún no ha llegado a los sabores ESTABLE o LIBERACIÓN de FreeBSD, pero según los informes está en ACTUAL.

Para obtener esto en la versión de MacOS grep, que se deriva de FreeBSD bsdgrep, consulte a Apple. ☺

Otras lecturas

JdeBP
fuente
Agradable, y gracias por informar sobre esto. Esta respuesta me parecería aún más fascinante si citara el código con errores.
dhag
1

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

produce:

-----
 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

En un 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

Más detalles sobre cgrep, disponible a través de brew, y de 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)

salud, drl

drl
fuente
Acabo de conseguir un nuevo grep.
Tim
@Tim - Espero que encuentres a cgrep tan útil como yo. La velocidad en las pruebas que he hecho lo puso aproximadamente a la par con GNU grep, y las características de "contexto / ventanas" son muy útiles. También se construye fácilmente en sistemas Linux ... salud, drl
drl