Solución:
El complemento de s
es S
, no [^s]
que (con la ayuda de -i
) excluyó ‘SIX’ y ‘Sam’ del resultado porque contienen un literal s
.
Cómo grep -i
para las líneas que comienzan con “host”, seguidas de uno o más espacios en blanco y una secuencia de uno o más caracteres hasta el final de la línea, donde no hay literal *
o pueden existir espacios en blanco:
grep -Ei '^host[[:space:]]+[^*[:space:]]+$' file
Host opengrok-01-Eight
Host opengrok-02-SIX
Host opengrok-03-forMe
Host opengrok-04-ForSam
Host opengrok-05-Okay
Interpretación s
ya que el espacio en blanco es una extensión de GNU Grep. No está definido en POSIX. BSD Grep, por ejemplo, no identifica s
como espacio en blanco. Las expresiones regulares de Perl también son una extensión de POSIX, pero tanto BSD como GNU lo proporcionan. Para una expresión totalmente portátil, debe usar [[:space:]]
en lugar de.
El manual GNU Grep establece de forma algo vaga que “la mayoría de los metacaracteres pierden su significado especial dentro de las expresiones entre corchetes”. Has encontrado que s
es uno de ellos, y de hecho POSIX especifica (nuevamente) que los caracteres especiales .
, *
, [
and should lose their special meaning within a bracket expression. But you can still portably use
[:space:]
.
Entonces, respondiendo a sus dos preguntas,
¿Cómo debería escribir mi
grep -E
¿para este caso?
grep -Ei '^host[[:space:]]+[^*[:space:]]+[[:space:]]*$'
¿Hay otras trampas desagradables que me haya perdido?
-E
o que me muerda si uso-P
?
Un error común es probar el Perl no codicioso. .*?
sin -P
bandera.
$ echo 'AB 14 34' | grep -Eo '^.*?4'
AB 14 34
$ echo 'AB 14 34' | grep -Po '^.*?4'
AB 14
$ echo 'AB 14 34' | grep -o '^.*?4'
{nothing}
La última palabra: BRE, ERE y PRE son todos diferentes. ¡Conozca sus expresiones regulares!