อะไรคือความแตกต่างระหว่าง "grep", "egrep" และ "fgrep"


273

ทุกคนสามารถบอกความแตกต่างทางเทคนิคระหว่างgrep, egrepและfgrepและยกตัวอย่างที่เหมาะสม?

เมื่อฉันจะต้องใช้grepมากกว่าegrepและในทางกลับกัน?


7
superuser มีภาพประกอบที่ยอดเยี่ยมของความแตกต่างระหว่าง grep, egrep, fgrep และ pgrep: superuser.com/questions/508881/…
Eric Leschinski

คำตอบ:


292
  • egrep เท่ากับ 100% grep -E
  • fgrep เท่ากับ 100% grep -F

ในอดีตสวิตช์เหล่านี้มีให้ในไบนารีแยกกัน ในระบบ Unix ที่เก่าแก่จริงๆคุณจะพบว่าคุณจำเป็นต้องโทรหาไบนารีที่แยกจากกัน แต่ในระบบที่ทันสมัย man page สำหรับ grep มีรายละเอียดเกี่ยวกับเรื่องนี้

สำหรับสิ่งที่พวกเขาทำ-Eสวิตช์ grep เป็นโหมดพิเศษเพื่อให้นิพจน์ได้รับการประเมินว่าเป็น ERE (Extended Regular Expression) ซึ่งตรงข้ามกับการจับคู่รูปแบบปกติ รายละเอียดของไวยากรณ์นี้อยู่ในหน้าคน

-E, --extended-regexp
ตีความรูปแบบเป็นการแสดงออกปกติเพิ่มเติม

-Fสวิทช์สวิทช์ grep เข้าสู่โหมดที่แตกต่างกันที่จะยอมรับรูปแบบเพื่อให้ตรง แต่แล้วแยกรูปแบบที่ขึ้นเป็นสตริงการค้นหาต่อหนึ่งบรรทัดและไม่ค้นหาหรือที่ใด ๆ ของสายโดยไม่ต้องทำจับคู่รูปแบบใด ๆ เป็นพิเศษ

-F, --fixed-strings
ตีความรูปแบบเป็นรายการของสตริงคงที่คั่นด้วยบรรทัดใหม่ใด ๆ ที่จะถูกจับคู่

นี่คือตัวอย่างบางสถานการณ์:

  • คุณมีไฟล์ที่มีรายการชื่อผู้ใช้ Unix พูดถึงสิบข้อความในรูปแบบข้อความธรรมดา คุณต้องการค้นหาไฟล์กลุ่มในเครื่องของคุณเพื่อดูว่ามีผู้ใช้ใด ๆ ในสิบรายที่อยู่ในกลุ่มพิเศษหรือไม่:

    grep -F -f user_list.txt /etc/group
    

    เหตุผลที่-Fสวิตช์ช่วยได้ที่นี่คือชื่อผู้ใช้ในไฟล์รูปแบบของคุณถูกตีความว่าเป็นสตริงข้อความธรรมดา ตัวอย่างเช่นจุดจะถูกตีความว่าเป็นจุดแทนที่จะเป็นไวด์การ์ด

  • คุณต้องการค้นหาโดยใช้นิพจน์แฟนซี ตัวอย่างเช่นวงเล็บ()สามารถใช้เพื่อระบุกลุ่มที่|ใช้เป็นตัวดำเนินการ OR คุณสามารถเรียกใช้การค้นหานี้โดยใช้-E:

    grep -E '^no(fork|group)' /etc/group
    

    ... เพื่อส่งคืนบรรทัดที่ขึ้นต้นด้วย "nofork" หรือ "nogroup" หากไม่มี-Eสวิตช์คุณจะต้องหลีกเลี่ยงอักขระพิเศษที่เกี่ยวข้องเพราะด้วยการจับคู่รูปแบบปกติพวกเขาจะค้นหารูปแบบที่แน่นอนนั้น

    grep '^no\(fork\|group\)' /etc/group
    

17
บางระบบไม่ได้egrepหรือfgrep; -Eและ-Fเป็นมาตรฐาน จริงๆแล้วมันมีความเข้ากันไม่ได้ขนาดเล็กในegrep: มันปฏิบัติ{แตกต่างกันเล็กน้อย
Gilles

4
fgrepใช้แบ็กเอนด์ Aho-Corasick ในขณะที่grepใช้ Commentz-Walter เวอร์ชันที่แก้ไข ซึ่งหมายความว่าgrepมีกรณี O (mn) fgrepที่แย่ที่สุดในขณะที่ O (m + n) ที่แย่ที่สุด
Slater Victoroff

2
Gilles "au contraire mon capitan", ระบบบางระบบ (เก่ากว่าอาจ) อาจไม่มีตัวเลือก -F สำหรับ grep มาตรฐาน แต่มี fgrep, ppl บางคนบ่นเกี่ยวกับเรื่องนี้ในหัวข้อเดิมที่ฉันพบเกี่ยวกับการใช้ grep สำหรับอักขระพิเศษ
THESorcerer

ฉันเพิ่งเกิดขึ้นเมื่อระบบ Android ที่egrepและgrep -Eถูกจัดการโดย executables ที่แตกต่างกันและ BusyBox BSD grep ทั้งสองสายพันธุ์มีพฤติกรรมที่แตกต่างสำหรับการไม่ Posix สร้าง regex \sเช่น สิ่งนี้นำไปสู่ความสับสนมาก ...
Lii

33

จากman grep:

 egrep เหมือนกับ grep -E
 fgrep เหมือนกับ grep -F การร้องขอโดยตรงเช่น egrep หรือ  
  fgrep เลิกใช้แล้ว แต่มีให้เพื่ออนุญาตแอปพลิเคชันเชิงประวัติ
  ที่พึ่งพาพวกเขาเพื่อให้ไม่ได้รับการแก้ไข

คุณใช้fgrepหรือgrep -Fหากคุณไม่ต้องการให้ตีความสายอักขระ grepped เป็นรูปแบบ

คุณใช้egrepหรือgrep -Eถ้าคุณต้องการใช้ regexp แบบขยาย


13

egrepและfgrepโดยทั่วไปเทียบเท่าgrep -Eและgrep -F(ตามลำดับ):

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

ข้อความผิดพลาดอาจแตกต่างกัน


2
ok แต่สิ่งที่เป็นการแสดงออกปกติขยาย? มันไม่ได้อธิบายด้านล่างจริงๆ ตัวอย่างเล็ก ๆ น้อย ๆ จะดี ...
isomorphismes

@ isomorphismes: ลิงก์ wikibooksนี้อธิบายได้ดี ...
zb226

8

จาก "man grep":

มีโปรแกรมให้เลือกใช้สามโปรแกรมเช่นreprep, fgrep และ rgrep egrep เหมือนกับ grep -E fgrep เหมือนกับ grep -F rgrep เหมือนกับ grep -r การเรียกใช้โดยตรงเช่น egrep หรือ fgrep นั้นไม่ได้รับการสนับสนุน แต่มีไว้เพื่ออนุญาตให้แอปพลิเคชันทางประวัติศาสตร์ที่พึ่งพาพวกเขาให้เรียกใช้งานที่ไม่ได้แก้ไข


2
คำถามถามถึงตัวอย่างที่เหมาะสม
isomorphismes

3

หากคุณค้นหาสตริงคำต่อคำและต้องการตรวจสอบให้แน่ใจว่าสตริงที่คุณส่งผ่านถูกตีความเป็นคำต่อคำ (เช่นโดยไม่เสี่ยงที่พูดว่าเครื่องหมายจุดหรือเครื่องหมายคำถามจะถูกตีความเป็นอย่างอื่น) ให้ใช้ fgrep หรือ egrep -F

สำหรับความแตกต่างระหว่าง egrep และ grep ฉันคิดว่า egrep เป็นเวลาที่คุณต้องการ ไซต์ GNU ด้วยตนเองแสดงรายการความแตกต่างระหว่าง grep และ egrep ซึ่งดูเหมือนว่าจะอยู่ในรูปแบบของไวยากรณ์: บางสิ่งจำเป็นต้องใช้สแลชในขณะที่สิ่งอื่นไม่ทำ ฉันคิดว่า egrep นั้น "เข้ากันได้" มากกว่าด้วย perl regexps และ javascript regexps ดังนั้นฉันจึงใช้ egrep ได้ง่ายขึ้น

Btw ผมขอแนะนำให้คุณแอ๊ลอง - จะสนับสนุน pregs และมีค่าเริ่มต้นที่มีประโยชน์มากขึ้น (เช่นสีข้ามไดเรกทอรีอาจจะไม่สิ่งที่คุณอยากเหมือน .svn ความสามารถในการปฏิบัติตาม symlinks และมันเป็นบิตง่ายต่อการพิมพ์ ack มากกว่า grep -E)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.