Encuentra la cadena exacta con grep

9

a modo de ejemplo, tengo un gran archivo de texto con muchas direcciones de correo electrónico, usando bash necesito buscar / verificar que exista un correo electrónico (o no). ¿Se deben usar (solo) los "anclajes"?

grep '^[email protected]' text_file

o hay mejores maneras? Necesito crear un script bash y me gustaría estar a salvo.

Pol Hallen
fuente
1
¿Es el correo electrónico la única palabra en una línea?
Glenn Jackman
de hecho: el archivo tiene este formato: [email protected] example.com/user1
Pol Hallen
1
En ese caso, lo usaría grep -q '^user1@example\.com\>', con un ancla de línea al comienzo y un ancla de fin de palabra al final.
Glenn Jackman
stackoverflow.com/questions/4709912/how-to-grep-the-exact-match
Ciro Santilli 冠状 病毒 审查 六四 事件 法轮功

Respuestas:

24

Vea las opciones -F(cadena fija, en lugar de expresión regular) y -x(exacto: coincida con la línea completa).

grep -Fx [email protected] text_file

sería el equivalente de:

grep '^user1@example\.com$' text_file

(recuerde que .es un operador de expresión regular que coincide con cualquier carácter).

Use la -qopción si solo desea verificar si existe esa línea:

grep -Fxq [email protected] text_file &&
  echo yes, that address is in that file.

Si la línea a buscar y el nombre del archivo son variables:

grep -Fxqe "$email" < "$file"

O

grep -Fxq -- "$email" < "$file"

No quieres:

grep -Fxq "$email" "$file"

ya que ello causar problemas si $emailo $fileempezar con -.

Si el archivo está ordenado (en su localidad actual, preferiblemente C), puede acelerar las cosas usando en commlugar de grep:

printf '%s\n' [email protected] | comm -12 - text_file

La ventaja será más evidente cuando tenga varias direcciones de correo electrónico para verificar (por ejemplo, en otro archivo ordenado):

comm -12 text_file emails_to_check

sería más rápido que:

grep -Fxf emails_to_check text_file
Stéphane Chazelas
fuente
AFAIK, grep -Fxq -- "$email" "$file"también funciona.
vinc17
stephane, ¿por qué cambiaste de una entrada de archivo (manejada por grep) a stdin usando el <redirector? ¿hay alguna ventaja?
umläute
@ umläute y vinc17. Como dije, es para cubrir los nombres de archivos que comienzan con -. incluso grep -- "$email" "$file"sería un problema para un archivo llamado -(que greptrata especialmente como stdin de significado )
Stéphane Chazelas
6

Para ser lo más eficiente posible, desea detenerse después de encontrar la primera coincidencia. Si tiene GNU grep, puede hacer esto:

grep -m 1 '^user1@example\.com$' your_file

Si no lo hace, puede usar Perl:

perl -nlE 'say and last if $_ eq q{[email protected]}' your_file
Joseph R.
fuente
44
-mes específico de GNU. Utilice POSIX -qsi desea verificar de manera eficiente que exista dicha línea.
Stéphane Chazelas
3

Hay muchos cheques por correo electrónico allí. Uno de esos es:

grep -E -o "\b[a-zA-Z0-9.-]+@[a-zA-Z0-9.-]+\.[a-zA-Z0-9.-]+\b" text_file

Para elaborar mi respuesta.

Está utilizando el ^ancla que indica el inicio de la cadena. Esto no coincidirá si una dirección de correo electrónico está en algún lugar entre una cadena larga.

Valentin Bajrami
fuente
2
Gracias. Es una opción grep genérica para "extraer" todas las direcciones de correo electrónico dentro de un archivo. Necesito buscar una dirección de correo electrónico usando read EMAIL y luego usando grep para verificarlo.
Pol Hallen
2

su grepcomando coincidirá con todo lo que comienza ^[email protected], incluida la dirección de correo electrónico en sí, pero también [email protected]. dado que .es un carácter especial en expresiones regulares que coincide con cualquier tecla, debe escapar como\.

suponiendo que su archivo de texto contenga una dirección por línea, use:

EMAIL=user1@example\\.com
egrep "^${EMAIL}$" text_file

el final $se asegurará de que la línea termine después de la dirección de correo electrónico. También estoy usando comillas dobles ", ya que estas permiten usar variables (a diferencia de las comillas simples ')

umläute
fuente
1
Eso también coincide user1@example-com.
Stéphane Chazelas
@ StéphaneChazelas, por supuesto, tienes razón; Se actualizó la respuesta.
umläute
@ umläute Necesita duplicar la barra invertida. Pero es mejor usarlo -Fx.
vinc17
@ vinc17, doh; bash escapando; De todos modos, sí estoy de acuerdo en que es mejor para su uso -Fx, sino que los de Stephane respuesta :-)
Umlaute
0

Teniendo en cuenta la coincidencia de cadena literal / exacta general:

grep -w "search_word" <file>  >  output.txt

#\b shows boundaries over here.

o,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
123Usuario
fuente