Câu trả lời:
Trong lịch sử các công tắc này được cung cấp trong các nhị phân riêng biệt. Trên một số hệ thống Unix thực sự cũ, bạn sẽ thấy rằng bạn cần gọi các nhị phân riêng biệt, nhưng trên tất cả các hệ thống hiện đại, các công tắc được ưu tiên. Trang người đàn ông cho grep có chi tiết về điều này.
Đối với những gì họ làm, -E
chuyển grep sang chế độ đặc biệt để biểu thức được đánh giá là ERE (Biểu thức chính quy mở rộng) trái ngược với so khớp mẫu thông thường. Chi tiết về cú pháp này là trên trang người đàn ông.
-E, --extended-regexp
Giải thích MẪU như một biểu thức chính quy mở rộng
Công -F
tắc chuyển grep sang một chế độ khác trong đó nó chấp nhận một mẫu để khớp, nhưng sau đó chia mẫu đó thành một chuỗi tìm kiếm trên mỗi dòng và thực hiện tìm kiếm HOẶC trên bất kỳ chuỗi nào mà không thực hiện bất kỳ khớp mẫu đặc biệt nào.
-F, --fixed-strings
Giải thích MẪU như một danh sách các chuỗi cố định, được phân tách bằng các dòng mới, bất kỳ chuỗi nào sẽ được khớp.
Dưới đây là một số tình huống ví dụ:
Bạn có một tệp với danh sách mười tên người dùng Unix ở dạng văn bản thuần túy. Bạn muốn tìm kiếm tệp nhóm trên máy của mình để xem liệu có bất kỳ ai trong số mười người dùng được liệt kê trong bất kỳ nhóm đặc biệt nào không:
grep -F -f user_list.txt /etc/group
Lý do -F
chuyển đổi giúp ở đây là tên người dùng trong tệp mẫu của bạn được hiểu là các chuỗi văn bản thuần túy. Các dấu chấm chẳng hạn sẽ được hiểu là các dấu chấm thay vì các ký tự đại diện.
Bạn muốn tìm kiếm bằng cách sử dụng một biểu thức ưa thích. Ví dụ, dấu ngoặc đơn ()
có thể được sử dụng để chỉ ra các nhóm |
được sử dụng làm toán tử OR. Bạn có thể chạy tìm kiếm này bằng cách sử dụng -E
:
grep -E '^no(fork|group)' /etc/group
... để trả về các dòng bắt đầu bằng "nofork" hoặc "nogroup". Nếu không có công -E
tắc, bạn sẽ phải thoát các ký tự đặc biệt có liên quan vì với khớp mẫu bình thường, họ sẽ chỉ tìm kiếm mẫu chính xác đó;
grep '^no\(fork\|group\)' /etc/group
egrep
hoặc fgrep
; -E
và -F
là tiêu chuẩn. Thực tế có những không tương thích nhỏ trong egrep
: nó đối xử {
hơi khác nhau.
fgrep
sử dụng phụ trợ Aho-Corasick, trong khi grep
sử dụng phiên bản sửa đổi của Commentz-Walter. Điều này có nghĩa là grep
có độ phức tạp O (mn) fgrep
tồi tệ nhất trong khi ở mức tồi tệ nhất là O (m + n).
egrep
và grep -E
được xử lý bởi các tệp thực thi khác nhau, BusyBox và BSD grep. Hai biến thể có sự khác biệt về hành vi đối với các cấu trúc regex không Posix, chẳng hạn như \s
. Điều này dẫn đến nhiều nhầm lẫn ...
Từ man grep
:
egrep giống như grep -E. fgrep giống như grep -F. Gọi trực tiếp như egrep hoặc fgrep không được dùng nữa, nhưng được cung cấp để cho phép các ứng dụng lịch sử mà dựa vào họ để chạy không thay đổi.
Bạn sử dụng fgrep
hoặc grep -F
nếu bạn không muốn chuỗi grepping được hiểu là một mẫu.
Bạn sử dụng egrep
hoặc grep -E
nếu bạn cần sử dụng một biểu thức chính mở rộng.
egrep
và fgrep
về cơ bản tương đương với grep -E
và grep -F
(tương ứng):
-E, --extended-regexp
Interpret PATTERN as an extended regular expression (ERE, see
below). (-E is specified by POSIX.)
-F, --fixed-strings
Interpret PATTERN as a list of fixed strings, separated by
newlines, any of which is to be matched. (-F is specified by
POSIX.)
Thông báo lỗi có thể khác nhau mặc dù.
Từ "người đàn ông grep":
ba chương trình biến thể egrep, fgrep và rgrep có sẵn. egrep giống như grep -E. fgrep giống như grep -F. rgrep giống như grep -r. Yêu cầu trực tiếp như egrep hoặc fgrep không được chấp nhận, nhưng được cung cấp để cho phép các ứng dụng lịch sử dựa vào chúng chạy không thay đổi.
Nếu bạn tìm kiếm một chuỗi nguyên văn và muốn chắc chắn rằng chuỗi bạn đã vượt qua được hiểu nguyên văn (nghĩa là không có nguy cơ nói rằng dấu chấm hoặc dấu hỏi sẽ được hiểu là một thứ khác), hãy sử dụng fgrep hoặc egrep -F.
Đối với sự khác biệt giữa egrep và grep, tôi nghĩ rằng egrep hầu hết là điều bạn muốn. Trang web hướng dẫn GNU liệt kê sự khác biệt giữa grep và egrep dường như nằm trong cú pháp: một số thứ yêu cầu gạch chéo trong khi những thứ khác thì không. Tôi nghĩ rằng egrep "tương thích" hơn với regexps perl và regexps javascript nên tôi dễ sử dụng egrep hơn.
Btw. Tôi thực sự khuyến khích bạn dùng thử ack - nó hỗ trợ PREG và có các mặc định hữu ích hơn (ví dụ như tô màu, bỏ qua các thư mục có thể không phải là những gì bạn muốn như .svn, khả năng theo liên kết tượng trưng và dễ dàng nhập hơn một chút ack hơn grep -E).