ทุกคนสามารถบอกความแตกต่างทางเทคนิคระหว่างgrep
, egrep
และfgrep
และยกตัวอย่างที่เหมาะสม?
เมื่อฉันจะต้องใช้grep
มากกว่าegrep
และในทางกลับกัน?
ทุกคนสามารถบอกความแตกต่างทางเทคนิคระหว่างgrep
, egrep
และfgrep
และยกตัวอย่างที่เหมาะสม?
เมื่อฉันจะต้องใช้grep
มากกว่าegrep
และในทางกลับกัน?
คำตอบ:
ในอดีตสวิตช์เหล่านี้มีให้ในไบนารีแยกกัน ในระบบ 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
egrep
หรือfgrep
; -E
และ-F
เป็นมาตรฐาน จริงๆแล้วมันมีความเข้ากันไม่ได้ขนาดเล็กในegrep
: มันปฏิบัติ{
แตกต่างกันเล็กน้อย
fgrep
ใช้แบ็กเอนด์ Aho-Corasick ในขณะที่grep
ใช้ Commentz-Walter เวอร์ชันที่แก้ไข ซึ่งหมายความว่าgrep
มีกรณี O (mn) fgrep
ที่แย่ที่สุดในขณะที่ O (m + n) ที่แย่ที่สุด
egrep
และgrep -E
ถูกจัดการโดย executables ที่แตกต่างกันและ BusyBox BSD grep ทั้งสองสายพันธุ์มีพฤติกรรมที่แตกต่างสำหรับการไม่ Posix สร้าง regex \s
เช่น สิ่งนี้นำไปสู่ความสับสนมาก ...
จากman grep
:
egrep เหมือนกับ grep -E fgrep เหมือนกับ grep -F การร้องขอโดยตรงเช่น egrep หรือ fgrep เลิกใช้แล้ว แต่มีให้เพื่ออนุญาตแอปพลิเคชันเชิงประวัติ ที่พึ่งพาพวกเขาเพื่อให้ไม่ได้รับการแก้ไข
คุณใช้fgrep
หรือgrep -F
หากคุณไม่ต้องการให้ตีความสายอักขระ grepped เป็นรูปแบบ
คุณใช้egrep
หรือgrep -E
ถ้าคุณต้องการใช้ regexp แบบขยาย
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.)
ข้อความผิดพลาดอาจแตกต่างกัน
จาก "man grep":
มีโปรแกรมให้เลือกใช้สามโปรแกรมเช่นreprep, fgrep และ rgrep egrep เหมือนกับ grep -E fgrep เหมือนกับ grep -F rgrep เหมือนกับ grep -r การเรียกใช้โดยตรงเช่น egrep หรือ fgrep นั้นไม่ได้รับการสนับสนุน แต่มีไว้เพื่ออนุญาตให้แอปพลิเคชันทางประวัติศาสตร์ที่พึ่งพาพวกเขาให้เรียกใช้งานที่ไม่ได้แก้ไข
หากคุณค้นหาสตริงคำต่อคำและต้องการตรวจสอบให้แน่ใจว่าสตริงที่คุณส่งผ่านถูกตีความเป็นคำต่อคำ (เช่นโดยไม่เสี่ยงที่พูดว่าเครื่องหมายจุดหรือเครื่องหมายคำถามจะถูกตีความเป็นอย่างอื่น) ให้ใช้ fgrep หรือ egrep -F
สำหรับความแตกต่างระหว่าง egrep และ grep ฉันคิดว่า egrep เป็นเวลาที่คุณต้องการ ไซต์ GNU ด้วยตนเองแสดงรายการความแตกต่างระหว่าง grep และ egrep ซึ่งดูเหมือนว่าจะอยู่ในรูปแบบของไวยากรณ์: บางสิ่งจำเป็นต้องใช้สแลชในขณะที่สิ่งอื่นไม่ทำ ฉันคิดว่า egrep นั้น "เข้ากันได้" มากกว่าด้วย perl regexps และ javascript regexps ดังนั้นฉันจึงใช้ egrep ได้ง่ายขึ้น
Btw ผมขอแนะนำให้คุณแอ๊ลอง - จะสนับสนุน pregs และมีค่าเริ่มต้นที่มีประโยชน์มากขึ้น (เช่นสีข้ามไดเรกทอรีอาจจะไม่สิ่งที่คุณอยากเหมือน .svn ความสามารถในการปฏิบัติตาม symlinks และมันเป็นบิตง่ายต่อการพิมพ์ ack มากกว่า grep -E)