วิธีใช้คำสั่ง grep บน Linux
grep
คำสั่งLinux คือยูทิลิตี้การจับคู่สตริงและรูปแบบที่แสดงบรรทัดที่ตรงกันจากไฟล์หลายไฟล์ นอกจากนี้ยังทำงานร่วมกับเอาต์พุตแบบ piped จากคำสั่งอื่น ๆ เราแสดงให้คุณเห็นว่า
เรื่องราวเบื้องหลัง grep
grep
คำสั่งที่มีชื่อเสียงใน Linux และ Unix วงการสำหรับเหตุผลที่สาม ประการแรกมันมีประโยชน์อย่างมาก ประการที่สองความมั่งคั่งของตัวเลือกสามารถท่วมท้น ประการที่สามมันถูกเขียนขึ้นในชั่วข้ามคืนเพื่อตอบสนองความต้องการเฉพาะ สองคนแรกปัง; อันที่สามดับเล็กน้อย
Ken Thompson ได้ดึงความสามารถในการค้นหานิพจน์ทั่วไปจากตัวed
แก้ไข (ออกเสียงว่า ee-dee) และสร้างโปรแกรมเล็ก ๆ ขึ้นมาเพื่อใช้ในการค้นหาไฟล์ข้อความ Doug Mcilroy หัวหน้าแผนกของเขาที่ Bell Labs เข้าหา Thompson และอธิบายถึงปัญหาที่ Lee McMahon เพื่อนร่วมงานคนหนึ่งของเขากำลังเผชิญอยู่
McMahon พยายามระบุผู้เขียนเอกสารของ Federalist ผ่านการวิเคราะห์ข้อความ เขาต้องการเครื่องมือที่สามารถค้นหาวลีและสตริงภายในไฟล์ข้อความ ธ อมป์สันใช้เวลาประมาณหนึ่งชั่วโมงในเย็นวันนั้นทำให้เครื่องมือของเขายูทิลิตี้ทั่วไปที่สามารถนำมาใช้โดยคนอื่น ๆ grep
และเปลี่ยนชื่อเป็น เขาใช้ชื่อจากed
สตริงคำสั่งg/re/p
ซึ่งแปลว่า“ การค้นหานิพจน์ทั่วไปทั่วโลก”
คุณสามารถดูทอมป์สันคุยกับ Brian Kernighan เกี่ยวกับการเกิดของgrep
.
ค้นหาง่ายๆด้วย grep
หากต้องการค้นหาสตริงภายในไฟล์ให้ส่งคำค้นหาและชื่อไฟล์ในบรรทัดคำสั่ง:
เส้นที่ตรงกันจะปรากฏขึ้น ในกรณีนี้จะเป็นเส้นเดียว ข้อความที่ตรงกันจะถูกเน้น เนื่องจากในการกระจายส่วนใหญ่grep
มีนามแฝงว่า:
นามแฝง grep = "grep --colour = auto"
ลองดูผลลัพธ์ที่มีหลายบรรทัดที่ตรงกัน เราจะมองหาคำว่า“ Average” ในไฟล์บันทึกแอปพลิเคชัน เนื่องจากเราจำไม่ได้ว่าคำนั้นเป็นตัวพิมพ์เล็กในไฟล์บันทึกหรือไม่เราจะใช้-i
ตัวเลือก ( ตัวพิมพ์เล็กและใหญ่):
grep -i ค่าเฉลี่ย geek-1.log
ทุกบรรทัดที่ตรงกันจะปรากฏขึ้นพร้อมกับไฮไลต์ข้อความที่ตรงกันในแต่ละบรรทัด
เราสามารถแสดงเส้นที่ไม่ตรงกันได้โดยใช้ตัวเลือก -v (กลับด้านตรงกัน)
grep -v Mem geek-1.log
ไม่มีการไฮไลต์เนื่องจากเป็นเส้นที่ไม่ตรงกัน
เราสามารถทำให้grep
เงียบสนิทได้ grep
ผลที่ได้จะถูกส่งผ่านไปยังเปลือกเป็นค่าตอบแทนจาก ผลของศูนย์หมายถึงสตริงถูกพบและเป็นผลมาจากหนึ่งหมายความว่ามันก็ไม่ได้พบ เราสามารถตรวจสอบโค้ดส่งคืนโดยใช้ $?
พารามิเตอร์พิเศษ:
grep -q เฉลี่ย geek-1.log
ก้อง $?
grep -q howtogeek geek-1.log
ก้อง $?
การค้นหาซ้ำด้วย grep
ในการค้นหาผ่านไดเร็กทอรีและไดเร็กทอรีย่อยที่ซ้อนกันให้ใช้อ็อพชัน -r (recursive) โปรดทราบว่าคุณไม่ได้ระบุชื่อไฟล์ในบรรทัดคำสั่งคุณต้องระบุเส้นทาง เรากำลังค้นหาในไดเรกทอรีปัจจุบัน“.” และไดเรกทอรีย่อยใด ๆ :
grep -r -i memfree
เอาต์พุตประกอบด้วยไดเร็กทอรีและชื่อไฟล์ของแต่ละบรรทัดที่ตรงกัน
เราสามารถ grep
ติดตามลิงก์สัญลักษณ์โดยใช้-R
ตัวเลือก (การหักล้างแบบวนซ้ำ) เรามีลิงก์สัญลักษณ์ในไดเร็กทอรีนี้ชื่อว่าlogs-folder
. /home/dave/logs
มันชี้ไปที่
ls -l บันทึกโฟลเดอร์
มาทำการค้นหาครั้งสุดท้ายของเราซ้ำด้วย -R
ตัวเลือก (การหักล้างแบบเรียกซ้ำ):
grep -R -i memfree
ตามด้วยลิงก์สัญลักษณ์และไดเรกทอรีที่ชี้ไปก็ถูกค้นหาด้วยgrep
เช่นกัน
ค้นหาทั้งคำ
โดยค่าเริ่มต้นgrep
จะจับคู่บรรทัดหากเป้าหมายการค้นหาปรากฏที่ใดก็ได้ในบรรทัดนั้นรวมถึงภายในสตริงอื่นด้วย ดูตัวอย่างนี้ เราจะค้นหาคำว่า "ฟรี"
grep -i ฟรี geek-1.log
ผลลัพธ์คือบรรทัดที่มีสตริง "ว่าง" อยู่ แต่ไม่ใช่คำที่แยกจากกัน เป็นส่วนหนึ่งของสตริง "MemFree"
หากต้องการบังคับgrep
ให้จับคู่ "คำ" ที่แยกจากกันเท่านั้นให้ใช้-w
ตัวเลือก (คำ regexp)
grep -w -i ฟรี geek-1.log
ก้อง $?
ครั้งนี้ไม่มีผลลัพธ์เนื่องจากข้อความค้นหา "ฟรี" ไม่ปรากฏในไฟล์เป็นคำแยกต่างหาก
การใช้คำค้นหาหลายคำ
-E
(regexp ขยาย) ตัวเลือกที่ช่วยให้คุณสามารถค้นหาคำหลายคำ ( -E
ตัวเลือกนี้แทนที่egrep
เวอร์ชันที่เลิกใช้แล้วของgrep
)
คำสั่งนี้จะค้นหาคำค้นหา 2 คำคือ“ average” และ“ memfree”
grep -E -w -i "average | memfree" geek-1.log
บรรทัดที่ตรงกันทั้งหมดจะแสดงสำหรับคำค้นหาแต่ละคำ
คุณยังสามารถค้นหาคำศัพท์หลายคำที่ไม่จำเป็นต้องเป็นทั้งคำ แต่ก็สามารถเป็นทั้งคำได้เช่นกัน
-e
(รูปแบบ) ตัวเลือกที่ช่วยให้คุณสามารถใช้คำค้นหาหลายในบรรทัดคำสั่ง เรากำลังใช้คุณลักษณะวงเล็บนิพจน์ทั่วไปเพื่อสร้างรูปแบบการค้นหา มันบอกgrep
ให้จับคู่อักขระใด ๆ ที่มีอยู่ในวงเล็บ“ []” ซึ่งหมายความว่าgrep
จะจับคู่“ kB” หรือ“ KB” ตามที่ค้นหา
สตริงทั้งสองตรงกันและในความเป็นจริงบางบรรทัดมีทั้งสองสตริง
การจับคู่เส้นตรง
-x
(สาย regexp) จะตรงกับสายที่ทั้งเส้นตรงกับคำค้นหา ลองค้นหาการประทับวันที่และเวลาที่เราทราบว่าปรากฏเพียงครั้งเดียวในไฟล์บันทึก:
grep -x "20 ม.ค. - 06 15:24:35 น." geek-1.log
พบและแสดงบรรทัดเดียวที่ตรงกัน
สิ่งที่ตรงกันข้ามคือแสดงเฉพาะบรรทัดที่ไม่ตรงกัน สิ่งนี้จะมีประโยชน์เมื่อคุณกำลังดูไฟล์คอนฟิกูเรชัน ความคิดเห็นเป็นสิ่งที่ดี แต่บางครั้งก็ยากที่จะระบุการตั้งค่าจริงในหมู่พวกเขาทั้งหมด นี่คือ/etc/sudoers
ไฟล์:
เราสามารถกรองบรรทัดความคิดเห็นได้อย่างมีประสิทธิภาพดังนี้:
sudo grep -v "#" / etc / sudoers
การแยกวิเคราะห์ง่ายกว่ามาก
แสดงเฉพาะข้อความที่ตรงกัน
อาจมีบางครั้งที่คุณไม่ต้องการเห็นบรรทัดที่ตรงกันทั้งหมดเพียงแค่ข้อความที่ตรงกัน -o
(เฉพาะการจับคู่) ตัวเลือกที่ไม่เพียงแค่นั้น
grep -o MemFree geek-1.log
การแสดงจะลดลงเพื่อแสดงเฉพาะข้อความที่ตรงกับคำค้นหาแทนที่จะเป็นบรรทัดที่ตรงกันทั้งหมด
การนับด้วย grep
grep
ไม่ได้เป็นเพียงแค่ข้อความเท่านั้น แต่ยังสามารถให้ข้อมูลที่เป็นตัวเลขได้อีกด้วย เราสามารถgrep
นับให้เราได้หลายวิธี หากเราต้องการทราบจำนวนครั้งที่ข้อความค้นหาปรากฏในไฟล์เราสามารถใช้-c
ตัวเลือก (count)
grep -c เฉลี่ย geek-1.log
grep
รายงานว่าข้อความค้นหาปรากฏ 240 ครั้งในไฟล์นี้
คุณสามารถgrep
แสดงหมายเลขบรรทัดสำหรับแต่ละบรรทัดที่ตรงกันได้โดยใช้-n
ตัวเลือก (หมายเลขบรรทัด)
grep -n ม.ค. geek-1.log
หมายเลขบรรทัดสำหรับแต่ละบรรทัดที่ตรงกันจะแสดงที่จุดเริ่มต้นของบรรทัด
ในการลดจำนวนผลลัพธ์ที่แสดงให้ใช้-m
ตัวเลือก (จำนวนสูงสุด) เราจะ จำกัด ผลลัพธ์ไว้ที่ห้าบรรทัดที่ตรงกัน:
grep -m5 -n ม.ค. geek-1.log
การเพิ่มบริบท
ความสามารถในการดูบรรทัดเพิ่มเติมบางบรรทัดซึ่งอาจไม่ตรงกันสำหรับแต่ละบรรทัดที่ตรงกันมักมีประโยชน์ มันช่วยแยกแยะได้ว่าเส้นที่ตรงกันคือเส้นที่คุณสนใจ
หากต้องการแสดงบางบรรทัดหลังบรรทัดที่ตรงกันให้ใช้ตัวเลือก -A (หลังบริบท) เราขอสามบรรทัดในตัวอย่างนี้:
grep -A 3 -x "20-Jan-06 15:24:35" geek-1.log
หากต้องการดูบางบรรทัดจากก่อนบรรทัดที่ตรงกันให้ใช้-B
ตัวเลือก (บริบทก่อนหน้า)
grep -B 3 -x "20 ม.ค. 06 15:24:35 น." geek-1.log
และหากต้องการรวมบรรทัดจากก่อนและหลังบรรทัดที่ตรงกันให้ใช้-C
ตัวเลือก (บริบท)
grep -C 3 -x "20-Jan-06 15:24:35" geek-1.log
กำลังแสดงไฟล์ที่ตรงกัน
หากต้องการดูชื่อไฟล์ที่มีคำค้นหาให้ใช้-l
ตัวเลือก (files with match) ในการค้นหาว่าไฟล์ซอร์สโค้ด C ใดมีการอ้างอิงถึงsl.h
ไฟล์ส่วนหัวให้ใช้คำสั่งนี้:
grep -l "sl.h" * .c
ชื่อไฟล์จะแสดงรายการไม่ใช่บรรทัดที่ตรงกัน
และแน่นอนว่าเราสามารถค้นหาไฟล์ที่ไม่มีคำค้นหานั้นได้ -L
(ไฟล์โดยไม่ต้องแข่งขัน) ตัวเลือกที่ไม่เพียงแค่นั้น
grep -L "sl.h" * .c
จุดเริ่มต้นและจุดสิ้นสุดของบรรทัด
เราสามารถบังคับgrep
ให้แสดงเฉพาะการจับคู่ที่เป็นจุดเริ่มต้นหรือจุดสิ้นสุดของบรรทัด ตัวดำเนินการนิพจน์ทั่วไป“ ^” จะจับคู่จุดเริ่มต้นของบรรทัด บรรทัดทั้งหมดในล็อกไฟล์จะมีช่องว่าง แต่เราจะค้นหาบรรทัดที่มีช่องว่างเป็นอักขระตัวแรก:
grep "^" geek-1.log
บรรทัดที่มีช่องว่างเป็นอักขระตัวแรกที่จุดเริ่มต้นของบรรทัดจะปรากฏขึ้น
ในการจับคู่ส่วนท้ายของบรรทัดให้ใช้ตัวดำเนินการนิพจน์ทั่วไป“ $” เราจะค้นหาบรรทัดที่ลงท้ายด้วย“ 00”
grep "00 $" geek-1.log
หน้าจอจะแสดงบรรทัดที่มี“ 00” เป็นอักขระสุดท้าย
ใช้ท่อกับ grep
แน่นอนคุณสามารถไพพ์อินพุตไปยังgrep
ท่อเอาต์พุตจากgrep
ไปยังโปรแกรมอื่นและวางgrep
อยู่ตรงกลางของโซ่ท่อ
สมมติว่าเราต้องการดูการเกิดขึ้นทั้งหมดของสตริง“ ExtractParameters” ในไฟล์ซอร์สโค้ด C ของเรา เรารู้ว่าจะมีค่อนข้างน้อยดังนั้นเราจึงใส่ผลลัพธ์ลงในless
:
grep "ExtractParameters" * .c | น้อยกว่า
ผลลัพธ์จะถูกนำเสนอในรูปแบบless
.
สิ่งนี้ช่วยให้คุณสามารถเลื่อนดูรายชื่อไฟล์และใช้less's
เครื่องมือค้นหา
หากเราไพพ์เอาต์พุตจากgrep
เข้าwc
และใช้-l
อ็อพชัน (lines) เราสามารถนับจำนวนบรรทัดในไฟล์ซอร์สโค้ดที่มี“ ExtractParameters” ได้ (เราสามารถบรรลุสิ่งนี้ได้โดยใช้grep
-c
ตัวเลือก (count) แต่นี่เป็นวิธีที่เรียบร้อยในการสาธิตการวางท่อgrep
)
grep "ExtractParameters" * .c | wc -l
ที่มีคำสั่งต่อไปเรากำลังท่อส่งออกมาทางls
เข้าgrep
และท่อส่งออกจากเข้าgrep
sort
เรากำลังแสดงรายการไฟล์ในไดเร็กทอรีปัจจุบันโดยเลือกไฟล์ที่มีสตริง "ส.ค. " อยู่ในไฟล์และจัดเรียงตามขนาดไฟล์:
ls -l | grep "ส.ค. " | เรียงลำดับ + 4n
มาทำลายมัน:
- ls -l : แสดงรายการไฟล์ในรูปแบบยาวโดยใช้
ls
. - grep“ ส.ค. ” : เลือกบรรทัดจาก
ls
รายชื่อที่มี“ ส.ค. ” อยู่ โปรดทราบว่าจะพบไฟล์ที่มี“ ส.ค. ” อยู่ในชื่อด้วย - sort + 4n : เรียงลำดับผลลัพธ์จาก grep ในคอลัมน์ที่สี่ (ขนาดไฟล์)
เราได้รับรายชื่อไฟล์ทั้งหมดที่แก้ไขในเดือนสิงหาคม (โดยไม่คำนึงถึงปี) โดยเรียงตามขนาดไฟล์จากน้อยไปมาก
ที่เกี่ยวข้อง: วิธีใช้ Pipes บน Linux
grep: คำสั่งน้อยกว่าของพันธมิตร
grep
เป็นเครื่องมือที่ยอดเยี่ยมสำหรับคุณ 2517 และยังคงแข็งแกร่งเพราะเราต้องการสิ่งที่ทำและไม่มีอะไรจะดีไปกว่านี้
การเชื่อมต่อgrep
กับนิพจน์ทั่วไป - fu จะนำไปสู่อีกระดับ
ที่เกี่ยวข้อง: วิธีใช้นิพจน์ทั่วไปพื้นฐานเพื่อค้นหาได้ดีขึ้นและประหยัดเวลา