Encontre a string exata com grep

9

a título de exemplo, eu tenho um grande arquivo de texto com muitos endereços de email, usando o bash, preciso pesquisar / verificar se existe um email (ou não). Deve usar (apenas) as "âncoras"?

grep '^[email protected]' text_file

ou há maneiras melhores? Preciso criar um script bash e gostaria de estar seguro.

Pol Hallen
fonte
1
O e-mail é a única palavra em uma linha?
Glenn Jackman
de fato: o arquivo tem este formato: [email protected] example.com/user1
Pol Hallen
1
Nesse caso, eu usaria grep -q '^user1@example\.com\>'- com uma âncora de linha no início e uma âncora de fim de palavra no final.
Glenn Jackman
stackoverflow.com/questions/4709912/how-to-grep-the-exact-match
Ciro Santilli冠状病毒审查六四事件法轮功

Respostas:

24

Veja as opções -F(sequência fixa, em oposição à expressão regular) e -x(exata: coincide com a linha inteira).

grep -Fx [email protected] text_file

seria o equivalente a:

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

(lembre-se de que .é um operador de expressão regular que corresponde a qualquer caractere).

Use a -qopção se você quiser apenas verificar se existe essa linha:

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

Se a linha a pesquisar e o nome do arquivo forem variáveis:

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

Ou

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

Você não quer:

grep -Fxq "$email" "$file"

pois isso causaria problemas se $emailou $fileiniciado -.

Se o arquivo estiver classificado (no seu local atual, preferencialmente C), você poderá acelerar as coisas usando, em commvez de grep:

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

A vantagem se tornará mais óbvia quando você tiver vários endereços de email para verificar (por exemplo, em outro arquivo classificado):

comm -12 text_file emails_to_check

seria mais rápido que:

grep -Fxf emails_to_check text_file
Stéphane Chazelas
fonte
AFAIK, grep -Fxq -- "$email" "$file"também funciona.
vinc17
stephane, por que você mudou de uma entrada de arquivo (manipulada pelo grep) para stdin usando o <redirecionador? existem vantagens?
trema
@ umläute e vinc17. Como eu disse, é para cobrir nomes de arquivos começando com -. ainda grep -- "$email" "$file"seria um problema para um arquivo chamado -(que greptrata especialmente como significado stdin )
Stéphane Chazelas
6

Para ser o mais eficiente possível, você deseja parar depois que a primeira correspondência for encontrada. Se você possui o GNU grep, pode fazer o seguinte:

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

Caso contrário, você pode usar Perl:

perl -nlE 'say and last if $_ eq q{[email protected]}' your_file
Joseph R.
fonte
4
-mé específico do GNU. Use o POSIX -qse quiser verificar eficientemente se existe uma linha assim.
Stéphane Chazelas
3

Existem muitas verificações por email lá. Um deles é:

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

Para elaborar minha resposta.

Você está usando a ^âncora que indica o início da string. Isso não corresponderá se um endereço de email estiver em algum lugar entre uma string longa.

Valentin Bajrami
fonte
2
Obrigado. Essa é uma opção genérica de grep para "extrair" todos os endereços de email dentro de um arquivo. Preciso procurar um endereço de e-mail um por um usando read EMAIL e depois grep para verificá-lo.
Pol Hallen
2

seu grepcomando corresponderá a tudo o que começar ^[email protected], incluindo o próprio endereço de email, mas também [email protected]. como .é um caractere especial em expressões regulares que corresponde a qualquer tecla, você deve evitá-lo como\.

assumindo que seu arquivo de texto contenha um endereço por linha, use:

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

o final $garantirá que a linha termine após o endereço de email. Também estou usando aspas duplas ", pois elas permitem o uso de variáveis ​​(ao contrário das aspas simples ')

umläute
fonte
1
Isso também combina user1@example-com.
Stéphane Chazelas
@ StéphaneChazelas, é claro que você está certo; atualizou a resposta.
trema
@ umläute Você precisa dobrar a barra invertida. Mas é melhor usar -Fx.
vinc17
@ vinc17, doh; escape de festança; de qualquer forma, sim, eu concordo que é melhor para uso -Fx, mas isso é de Stephane resposta :-)
trema
0

Considerando correspondência literal / exata geral de seqüência de caracteres:

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

#\b shows boundaries over here.

ou,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
123Usuário
fonte