2 votos

Grep no parece encontrar todas las coincidencias en un archivo que espero

No estoy seguro si no entiendo completamente grep o si las expresiones regulares son la fuente de mi problema, así que tengo dos preguntas. Tengo un archivo de prueba simple llamado test.txt con el siguiente contenido:

$ cat test.txt Settings.xml blah Settings_1.xml blah Settings_2.xml

Cuando ejecuto grep en un directorio que contiene solo el archivo de prueba anterior con el siguiente comando, devuelve sin coincidencias:

$ grep -ir "Settings*xml"

*1) ¿Por qué el comodín `` no está capturando el punto?**

Y cuando ejecuto grep de la siguiente manera:

$ grep -ir "Settings*.xml"

siendo la única diferencia el punto después del comodín, los resultados son:

test.txt:Settings.xml

2) ¿Por qué grep no encuentra las otras dos coincidencias?

0 votos

Parece que el * no estaba haciendo lo que pensaba (ver la respuesta de @ArkadiuszDrabczyk). Una solución que sí devuelve lo que quiero es: $ grep -ir "Settings[[:alnum:][:punct:]]*.xml"

3voto

Arkadiusz Drabczyk Puntos 640

La razón es que * es un carácter especial en expresiones regulares y significa cero o más caracteres precedentes. Debes escapar * para que signifique un carácter literal * con \. Por lo tanto, en tus ejemplos:

grep -ir "Settings*xml"

buscaría una cadena que comience con Setting, y luego tenga cero o más caracteres s y xml al final. No hay tal cadena en tu archivo porque xml siempre está precedido por .. Y esto:

grep -ir "Settings*.xml"

buscaría una cadena que comience con Setting, y luego tenga cero o más caracteres s y .xml después de cero o más letras s.

Tu primer regex coincidiría con algo como esto:

Settingssxml

0 votos

Quieres decir * en tus primeras oraciones.

3voto

Kamil Maciorowski Puntos 897

Esta otra respuesta explica lo que sucedió, responde a tus preguntas explícitas. Mi respuesta está destinada a introducir un contexto más amplio.

Supongo que esperabas que * coincidiera con cero o más caracteres (cualquier carácter) y que . literalmente significara .. Esto funciona con la expansión de comodines de shell, es decir, si tuvieras archivos así:

$ ls -1
Ajustes.xml
blah
Ajustes_1.xml
Ajustes_2.xml

entonces (digamos, en bash) podrías hacer:

$ echo Ajustes*.xml
Ajustes.xml Ajustes_1.xml Ajustes_2.xml

No obtuviste lo que esperabas porque grep usa sintaxis de expresiones regulares donde:

  • . coincide con (casi) cualquier carácter,
  • * significa "cero o más caracteres precedentes",
  • \ hace que el siguiente carácter se interprete de forma literal.

Es por eso que en lugar de "Ajustes*.xml" deberías haber usado "Ajustes.*\.xml". En este caso:

  • .* hace lo que pensabas que haría *,
  • \. hace lo que pensabas que haría ..

EnMiMaquinaFunciona.com

EnMiMaquinaFunciona es una comunidad de administradores de sistemas en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros sysadmin, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X