Tìm chuỗi chính xác với grep


9

bằng ví dụ, tôi có một tệp văn bản lớn có nhiều địa chỉ email, sử dụng bash tôi cần tìm kiếm / xác minh rằng email tồn tại (hoặc không). Có nên sử dụng (chỉ) các "neo"?

grep '^user1@example.com' text_file

hoặc có cách nào tốt hơn? Tôi cần tạo một tập lệnh bash và tôi muốn được an toàn.


1
Email có phải là từ duy nhất trên một dòng không?
Glenn jackman

Thật vậy: tệp có định dạng này: user1@example.com example.com/user1
Pol Hallen

1
Trong trường hợp đó, tôi sẽ sử dụng grep -q '^user1@example\.com\>'- với một neo dòng ở đầu và một neo cuối từ ở cuối.
glenn jackman

Câu trả lời:


24

Xem các tùy chọn -F(chuỗi cố định, trái ngược với biểu thức chính quy) và -x(chính xác: khớp với toàn bộ dòng).

grep -Fx user1@example.com text_file

sẽ tương đương với:

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

(hãy nhớ rằng đó .là một toán tử biểu thức chính quy phù hợp với bất kỳ ký tự nào).

Sử dụng -qtùy chọn nếu bạn chỉ muốn kiểm tra nếu có một dòng như vậy:

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

Nếu dòng để tìm kiếm và tên tệp là biến:

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

Hoặc là

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

Bạn không muốn:

grep -Fxq "$email" "$file"

vì điều đó sẽ gây ra vấn đề nếu $emailhoặc $filebắt đầu với -.

Nếu tệp được sắp xếp (tốt nhất là tại địa phương hiện tại của bạn C), bạn có thể tăng tốc mọi thứ bằng cách sử dụng commthay vì grep:

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

Lợi thế sẽ trở nên rõ ràng hơn khi bạn có một vài địa chỉ email cần kiểm tra (ví dụ trong một tệp được sắp xếp khác):

comm -12 text_file emails_to_check

sẽ nhanh hơn:

grep -Fxf emails_to_check text_file

AFAIK, grep -Fxq -- "$email" "$file"cũng hoạt động.
vinc17

stephane, tại sao bạn chuyển từ một tập tin đầu vào (được xử lý bởi grep) sang stdin bằng cách sử dụng bộ <chuyển hướng? có lợi thế gì không?
umläute

@ umläute và vinc17. Như tôi đã nói, nó bắt đầu cho tên tập tin bắt đầu bằng -. thậm chí grep -- "$email" "$file"sẽ là một vấn đề đối với một tệp có tên -( grepcoi đặc biệt là stdin )
Stéphane Chazelas

6

Để hiệu quả nhất có thể, bạn muốn dừng lại sau khi trận đấu đầu tiên được tìm thấy. Nếu bạn có GNU grep, bạn có thể làm điều này:

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

Nếu bạn không, bạn có thể sử dụng Perl:

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

4
-mlà GNU cụ thể. Sử dụng POSIX -qnếu bạn muốn kiểm tra một cách hiệu quả rằng có một dòng như vậy.
Stéphane Chazelas

3

Có rất nhiều kiểm tra email ở đó. Một trong số đó là:

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

Để giải thích câu trả lời của tôi.

Bạn đang sử dụng ^neo cho biết bắt đầu chuỗi. Điều này sẽ không khớp nếu một địa chỉ email nằm ở đâu đó giữa một chuỗi dài.


2
Cảm ơn. Đó là một tùy chọn grep chung để "trích xuất" tất cả địa chỉ email bên trong một tệp. Tôi cần tìm kiếm từng địa chỉ email bằng cách đọc EMAIL sau đó sử dụng grep để kiểm tra nó.
Pol Hallen

2

greplệnh của bạn sẽ khớp với mọi thứ bắt đầu bằng ^user1@example.com, kể cả chính địa chỉ email user1@example.com.spammer.com. vì .là một ký tự đặc biệt trong các biểu thức chính quy khớp với bất kỳ phím nào, bạn nên thoát nó dưới dạng\.

giả sử rằng tệp văn bản của bạn chứa một địa chỉ trên mỗi dòng, hãy sử dụng:

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

theo dõi $sẽ đảm bảo rằng dòng kết thúc sau địa chỉ email. Tôi cũng đang sử dụng dấu ngoặc kép ", vì chúng cho phép sử dụng các biến (không giống như dấu ngoặc đơn ')


1
Điều đó cũng phù hợp user1@example-com.
Stéphane Chazelas

@ StéphaneChazelas bạn dĩ nhiên là đúng; cập nhật câu trả lời.
umläute

@ umläute Bạn cần tăng gấp đôi dấu gạch chéo ngược. Nhưng nó tốt hơn để sử dụng -Fx.
vinc17

@ vinc17, doh; bash thoát; dù sao đi nữa, vâng tôi đồng ý rằng tốt hơn là sử dụng -Fxnhưng đó là câu trả lời của stephane :-)
umläute

0

Xem xét kết hợp chuỗi chính xác / theo nghĩa đen:

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

#\b shows boundaries over here.

hoặc là,

 grep  "\bsearch_word\b"  <file>  >  output.txt 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.