Sự khác biệt giữa `grep`,` egrep` và` fgrep` là gì?


273

Bất cứ ai có thể cho tôi biết sự khác biệt giữa kỹ thuật grep, egrepfgrepvà cung cấp ví dụ thích hợp?

Khi nào tôi cần sử dụng grephơn egrepvà ngược lại?


7
superuser có một minh họa tuyệt vời về sự khác biệt giữa grep, egrep, fgrep và pgrep: superuser.com/questions/508881/
Kẻ

Câu trả lời:


292
  • egrep tương đương 100% với grep -E
  • fgrep tương đương 100% với grep -F

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, -Echuyể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 -Ftắ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 -Fchuyể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 -Etắ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
    

17
Một số hệ thống không có egrephoặc fgrep; -E-Flà 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.
Gilles

4
fgrepsử dụng phụ trợ Aho-Corasick, trong khi grepsử dụng phiên bản sửa đổi của Commentz-Walter. Điều này có nghĩa là grepcó độ phức tạp O (mn) fgreptồi tệ nhất trong khi ở mức tồi tệ nhất là O (m + n).
Slater Victoroff

2
Gilles "au contraire mon capitan", một số hệ thống (có lẽ cũ hơn) có thể không có tùy chọn -F cho grep tiêu chuẩn nhưng có một fgrep, một số người phàn nàn về điều đó trên chủ đề ban đầu tôi thấy về việc sử dụng grep cho các ký tự đặc biệt
THESorcerer

Gần đây tôi đã tình cờ thấy một hệ thống Android trên đó egrepgrep -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 ...
Lii

33

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 fgrephoặc grep -Fnếu bạn không muốn chuỗi grepping được hiểu là một mẫu.

Bạn sử dụng egrephoặc grep -Enếu bạn cần sử dụng một biểu thức chính mở rộng.


13

egrepfgrepvề cơ bản tương đương với grep -Egrep -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ù.


2
ok, nhưng những gì một biểu hiện thường xuyên mở rộng? Nó không thực sự giải thích dưới đây. Một vài ví dụ sẽ rất hay ...
đẳng cấu

@isomorphismes: Liên kết wikibooks này giải thích điều này một cách độc đáo ...
zb226

8

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.


2
Câu hỏi yêu cầu một ví dụ phù hợp.
đẳng cấu

3

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).

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.