วิธีใช้คำสั่ง 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 จะนำไปสู่อีกระดับ

ที่เกี่ยวข้อง: วิธีใช้นิพจน์ทั่วไปพื้นฐานเพื่อค้นหาได้ดีขึ้นและประหยัดเวลา