Linux/Unix Shell Scripting - Expresion regular y grep para encontrar los correos

   
Vista:

Expresion regular y grep para encontrar los correos

Publicado por Fer (21 intervenciones) el 24/10/2013 06:42:08
Hola, buenas.
Necesito extraer emails de una lista los cuales ademas deben estar escritos correctamente (sintax correcto).
He escrito un programita en VBA para access que usa esta expresion regular:

"[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,6})$"

y funciona muy bien en esa plataforma, pero es extremadamente lento.
Probando con linux hago esto en la consola:

sky@Demoledor:~/exemails/pruebasexp$ egrep -oi "[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,6})$" file.txt
egrep -oi "[a-z0-9"[a-z0-9%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9'*+/=?^_`{|}~-]+(?:\.[a-z0-9%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,6})$" file.txt
-bash: error sintáctico cerca del elemento inesperado `)'

Me he fijado que elimina los "#" en la repeticion que saca, asi que los elimino de la expresion y ejecuto de nuevo:

egrep -oi "[a-z0-9!$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,6})$" file.txt
egrep -oi "[a-z0-9+(?:[A-Z]{2,6})$" file.txt%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9+(?:[A-Z]{2,6})$" file.txt%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,6})$" file.txt
>

y me saca el ">".

Me sabria decir alguien porque no acepta los "#" y como se pueden incluir en la expresion regular si que de el error de arriba?.
Mas importante aun :-), que tendria que modificar para que la expresion sea aceptada y no me invite a meter datos (creo que es lo que hace el ">")
Repito que la expresion funciona perfectamente en VBA.
Expresiones mas sencillas, como esta que he encontrado por ahi:

egrep -io "([[:alnum:]_.-]+@[[:alnum:]_.-]+?\.[[:alpha:].]{2,6})" file.txt

funcionan perfectamente en la shell

Ya he leido que hay diferencia entre las expresiones regulares que se usan en los diferentes lenguaje, pero no he podido encontrar ningun documento que describa dichas diferencias.

Desde ya muchas gracias a toda la gente del foro, no es la primera vez que caigo por aqui y ciertamente es un lujo contar con la informacion y apollo brindado.
Saludos.
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder
Imágen de perfil de xve

Expresion regular y grep para encontrar los correos

Publicado por xve (254 intervenciones) el 24/10/2013 07:51:59
Hola Fer, vaya expresión regular.... la verdad es que me cuesta un montón de entender...

Cuando te muestra el signo ">", es porque hay alguna comilla que no esta cerrada, y te lo muestra para que sigas escribiendo la instrucción hasta cerrarla.

Sin ninguna duda, te recomiendo utilizar la instrucción que funciona en la shell, creo que es la manera correcta y rápida.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Expresion regular y grep para encontrar los correos

Publicado por Tom (253 intervenciones) el 24/10/2013 18:38:46
El shell examina los parámetros que van sin comillas o entre comillas dobles antes de pasárselos al comando en cuestión (en este caso grep).
Lo que has de hacer es usar comilla simple (') para encerrar toda la expresión regular. Si dentro de la RE ya tienes alguna comilla simple (me ha parecido ver que solamente dos) pecédela con backslash (\).

Podría quedar algo como esto:

1
'[a-z0-9!#$%&\'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[A-Z]{2,6})$'
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Expresion regular y grep para encontrar los correos

Publicado por fer (21 intervenciones) el 24/10/2013 19:54:36
Hola de nuevo, gracias por la atencion :-)

Bueno, yo tampoco la entiendo, la verdad.
Basicamente es bastante flexible en la parate local y mas restrictiva en la parte del host y el tipo de dominio y valida muy bien sobre las reglas de construccion establecidas.

Lo que comentas (xve) de usar la expresion que funciona no me vale, xq lo que pretendo es validar el email, y esa expresion se queda un poquito corta, por lo que me parece entender.
Quizas alguien que sabe de expresiones regulares podria adaptarla, pero yo no soy esa, la verdad :-), y como digo la otra que uso en vba es justo lo que necesito.

Tom, tomo nota de lo que comentas. Hasta mas tarde no podre probarlo, pero el \ me valdria para los "#" tambien? Porque veo que los has dejado en tu ejemplo y esos me provocaban el error de sintax.

Cunado pruebe comentare el resultado.
Un saludo, gracias :-)
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Expresion regular y grep para encontrar los correos

Publicado por Fer (21 intervenciones) el 25/10/2013 04:23:25
Buenas,
siento decir que no funciona lo del backslash.
He probado a encerrar la expresion en comillas simples y poner el backslash antes de las comillas simple dentro de la RE; tambien a encerrarla en comillas dobles y con el backslash delante de las comillas sencillas.
En ambos casos me muestra el simbolo ">"

Alguna otra idea o lugar donde pueda "traducir" la RE de VBA a la shell de linux?.

Gracias igualmente.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Expresion regular y grep para encontrar los correos

Publicado por Tom (253 intervenciones) el 25/10/2013 15:37:10
"El shell examina los parámetros que van sin comillas o entre comillas dobles antes de pasárselos al comando en cuestión (en este caso grep)."

Para el shell, el carácter # significa un comentario, ignorar hasta el fin de línea. Con la comilla simple deberías evitar que se interpreten esos caracteres, y se le pasen a egrep tal cual.

Con la expresión que yo he pegado, _no_ deberías tener ese problema del '>' (si la copias bien) pero podrías tener otro: que el formato de las RE de VBA no sea el mismo que el de las RE de unix.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

Expresion regular y grep para encontrar los correos

Publicado por Fer (21 intervenciones) el 25/10/2013 19:19:54
Gracasi de nuevo. Efectivamente las RE de VBA no necesariamente van en la shell.
De todos modos aqui tengo una que si funciona y que pasada sobre el mismo archivo de prueba de 2.700.000 emails elimina casi la misma cantidad de emails que la que uso en VBA con una diferencia de 150 sobre 300.000 email con sintax incorecto, lo cual me vale perfectamente y va asi:

grep -Eio '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$' fuente.txt > destino-sintaxok.txt

Para evitar problemas con caracteres null en el archivo (que grep no parece llevarlos bien y toma el archivo como binario) he encontrado 2 formas de proceder, ninguna testada lo suficiente todavia:

1. pasar previamente el archivo a unix asi:

dos2unix -f archivoDos.txt > archivoUnix.txt (o sin "> archivoUnix.txt" si no se quiere crear uno nuevo y sobreescribimos el original)

2. Usasr strings con grep asi:
strings fuente.txt | grep -Eio '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,6}$' > destino-sintaxok.txt

Ademas le he añadido el "^" al principio de la RE, un problema que no habia visto hasta ahora, y es que por ejemplo sin el admitia email que empezaban por comillas (") o las contenian, y aunque esta permitido su uso en la parte local daban problemas para importaciones etc.

Si no se usa strings junto grep o no se pasa el archivo a unix (creo que string va mejor y es mas pratico) saca 0 emails o solo unos pocos (2, 3, 4).

Bueno, espero mi experiencia sirva a alguien.
Una vez mas gracias por la atencion.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar