Grep ile tam dizeyi bulun


9

Örnek olarak, birçok e-posta adresi ile büyük bir metin dosyası var, bash kullanarak bir e-posta var (veya hayır) doğrulamak / doğrulamak gerekir. (Sadece) “ankrajlar” kullanılmalı mıdır?

grep '^user1@example.com' text_file

ya da daha iyi yollar var mı? Bir bash betiği oluşturmam gerekiyor ve güvende olmak istiyorum.


1
E-posta bir satırdaki tek kelime mi?
glenn jackman

gerçekten: dosya şu biçimde: user1@example.com example.com/user1
Pol Hallen

1
Bu durumda, grep -q '^user1@example\.com\>'başlangıçta bir çizgi çıpa ve sonunda bir kelime sonu çıpa ile kullanırım.
glenn jackman

Yanıtlar:


24

Bkz -F(sabit dize kadar normal ifadeye karşı) ve -x(: bütün çizgi maç tam) seçenekleri.

grep -Fx user1@example.com text_file

şuna eşdeğer olacaktır:

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

(bunun .herhangi bir karakterle eşleşen normal bir ifade operatörü olduğunu unutmayın ).

-qYalnızca böyle bir çizgi olup olmadığını kontrol etmek istiyorsanız seçeneği kullanın :

grep -Fxq user1@example.com text_file &&
  echo yes, that address is in that file.

Aranacak satır ve dosya adı değişkense:

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

Veya

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

İstemezsiniz:

grep -Fxq "$email" "$file"

eğer sorunlara sebep olacağından $emailya $fileile başladı -.

Dosyası (tercihen, geçerli yerel ayarda sıralanır varsa C) yapabilirsiniz kullanarak muhtemelen hız şeyler kadar commyerine grep:

printf '%s\n' user1@example.com | comm -12 - text_file

Kontrol edilecek birkaç e-posta adresiniz olduğunda (örneğin başka bir sıralı dosyada) avantaj daha belirgin hale gelecektir:

comm -12 text_file emails_to_check

daha hızlı olurdu:

grep -Fxf emails_to_check text_file

AFAIK grep -Fxq -- "$email" "$file"de çalışıyor.
vinc17

stephane, neden <yeniden yönlendirici kullanarak bir dosya girişinden (grep tarafından işlenir) stdin'e geçtiniz ? avantajları var mı?
umläute

@ umläute ve vinc17. Dediğim gibi, başından itibaren dosya adlarını kapsamaktadır -. Hatta grep -- "$email" "$file"adlı bir dosya için bir sorun olacağını -(ki grepözel anlam olarak davranır Stdin )
Stéphane Chazelas

6

Mümkün olduğunca verimli olabilmek için ilk maç bulunduktan sonra durmak istersiniz. GNU'nuz varsa grep, bunu yapabilirsiniz:

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

Bunu yapmazsanız Perl'i kullanabilirsiniz:

perl -nlE 'say and last if $_ eq q{user1@example.com}' your_file

4
-mGNU'ya özgüdür. -qBöyle bir çizgi olup olmadığını verimli bir şekilde kontrol etmek istiyorsanız POSIX'i kullanın .
Stéphane Chazelas

3

Orada bir sürü e-posta kontrolü var. Bunlardan biri:

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

Cevabımı detaylandırmak için.

^Dizenin başlangıcını gösteren bağlantıyı kullanıyorsunuz . Uzun bir dize arasında bir yerde bir e-posta adresi varsa, bu eşleşmez.


2
Teşekkürler. Bu, bir dosyadaki tüm e-posta adreslerini "ayıklamak" için genel bir grep seçeneğidir. Okumak için e-posta adresi kullanarak tek tek bir e-posta adresi aradıktan sonra kontrol etmek için grep kullanarak ihtiyacım var.
Pol Hallen

2

sizin grepkomut ile başlar her şey maç olacak ^user1@example.comama aynı zamanda, e-posta adresini kendisi dahil, user1@example.com.spammer.com. .düzenli ifadelerde herhangi bir tuşla eşleşen özel bir karakter olduğundan ,\.

metin dosyanızın satır başına bir adres içerdiğini varsayarsak, şunu kullanın:

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

sondaki $satırın e-posta adresinden sonra sona erdiğinden emin olur. Ben de çift tırnak kullanıyorum "bu (tek tırnak aksine değişkenleri kullanmasına izin olarak, ')


1
Bu da uyuyor user1@example-com.
Stéphane Chazelas

@ StéphaneChazelas elbette haklısın; cevabı güncelledi.
Umlaute

@ umläute Ters eğik çizgiyi iki katına çıkarmanız gerekir. Ama kullanmak daha iyi -Fx.
vinc17

@ vinc17, doh; bash kaçıyor; nasıl olsa, evet ben kullanmak daha iyi olduğunu kabul ediyorum -Fxama bu stephane cevabı :-)
umläute

0

Genel değişmez / tam dize eşleşmesi dikkate alındığında:

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

#\b shows boundaries over here.

veya,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.