El operador grep "+" no funciona

31

Esta

ls -l /var/log | awk '{print $9}' | grep "^[a-z]*\.log."

produce esto:

alternatives.log.1
alternatives.log.10.gz
alternatives.log.2.gz
alternatives.log.3.gz
alternatives.log.4.gz
alternatives.log.5.gz
alternatives.log.6.gz
alternatives.log.7.gz
alternatives.log.8.gz
alternatives.log.9.gz
apport.log.1
apport.log.2.gz
apport.log.3.gz

pero esto:

ls -l /var/log | awk '{print $9}' | grep "^[a-z]+\.log."

No produce nada.

¿Por qué? Acabo de cambiar *a +. ¿No es similar? El operador +solo necesita al menos una coincidencia y *cero o más.

Marko
fuente

Respuestas:

36

Esto se debe a que grep(sin ningún argumento) solo funciona con expresiones regulares estándar. +es parte de las expresiones regulares extendidas, por lo que para usar eso, debe usar grep -Eo egrep:

ls -l /var/log | awk '{print $9}' | grep -E "^[a-z]+\.log."

Además, puede hacer esto si no desea utilizar expresiones regulares extendidas:

ls -l /var/log | awk '{print $9}' | grep "^[a-z][a-z]*\.log."
MiJyn
fuente
Gracias. Ahora me refiero a esa solución, pero me preguntaba por qué "+" no funciona. Ahora sé. Gracias de nuevo.
Marko
11

Para profundizar en la respuesta de MiJyns, los "caracteres especiales" como + también funcionan en expresiones regulares estándar, pero debes escapar de ellos con una barra diagonal inversa. Se podría decir que las expectativas predeterminadas se invierten entre expresiones regulares y expresiones regulares extendidas:

En la expresión regular estándar, los caracteres coinciden literalmente de forma predeterminada. Por ejemplo, en grep "ab+"el + es un literal +. La expresión regular encontraría, por ejemplo, "ab + ab", pero no "abbbb". Para usar el "significado especial" de +, debe escapar de él. Entonces grep "ab\+"encontraría "abbb", pero ya no "ab + ab". Porque en el último ejemplo, el + se interpreta como el cuantificador "uno o muchos de eso", en ese caso "uno o muchos b".

En expresiones regulares extendidas es exactamente al revés. Aquí, debe escapar de "caracteres especiales" para ser tratado literalmente. Entonces grep -E "ab+"encuentra "abbb", pero no "ab + ab". Si escapas del +, se iguala literalmente. Entonces grep -E "ab\+"encuentra "ab + ab", pero no "abbb".

Henning Kockerbeck
fuente
1
Qué desastre legado ... ;-) como magia y supermagic re en vim. Urgh El precio a pagar por la compatibilidad con versiones anteriores ...
Rmano