วิธียกเว้นรูปแบบไฟล์และไดเรกทอรีด้วย grep

เผยแพร่แล้ว: 2022-06-29
แล็ปท็อป Linux แสดง bash prompt
fatmawati achmad zaenuri/Shutterstock.com

ตั้งแต่ปี 1974 คำสั่ง Linux grep ได้ช่วยเหลือผู้คนในการค้นหาสตริงในไฟล์ แต่บางครั้ง grep ก็ละเอียดเกินไป มีหลายวิธีที่จะบอกให้ grep เพิกเฉยต่อสิ่งต่าง ๆ

คำสั่ง grep

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

การเกิดของ grep ก่อนวันที่ Linux มันได้รับการพัฒนาในช่วงต้นทศวรรษ 1970 บน Unix ใช้ชื่อมาจากลำดับคีย์ g/re/p ในตัวแก้ไขบรรทัด ed (โดยบังเอิญ ออกเสียงว่า “ee-dee”) นี่ย่อมาจาก g lobal, re gular express search, p rint matching lines.

grep มีชื่อเสียง—บางที ฉาวโฉ่— ละเอียดถี่ถ้วนและใจเดียว บางครั้งมันจะค้นหาไฟล์หรือไดเร็กทอรีที่คุณต้องการโดยที่ไม่เสียเวลากับมัน เพราะผลลัพธ์ที่ได้อาจทำให้คุณมองไม่เห็นไม้สำหรับต้นไม้

วิธีใช้คำสั่ง grep บน Linux
วิธีใช้คำสั่ง grep บน Linux

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

ไม่รวมรูปแบบ

หากต้องการค้นหาด้วย grep คุณสามารถไพพ์อินพุตจากกระบวนการอื่น เช่น cat หรือคุณสามารถระบุชื่อไฟล์เป็นพารามิเตอร์บรรทัดคำสั่งสุดท้าย

เรากำลังใช้ไฟล์ขนาดสั้นที่มีข้อความของบทกวี Jabberwocky โดย Lewis Carroll ในสองตัวอย่างนี้ เรากำลังค้นหาบรรทัดที่ตรงกับข้อความค้นหา "Jabberwock"

 cat jabberwocky.txt | grep "จาเบอร์ว็อค"
 grep "Jabberwock" jabberwocky.text 

สองวิธีในการค้นหาไฟล์ข้อความเดียวกันด้วย grep

บรรทัดที่ตรงกับคำใบ้การค้นหาจะแสดงรายการสำหรับเรา โดยองค์ประกอบที่ตรงกันในแต่ละบรรทัดจะเน้นด้วยสีแดง นั่นคือการค้นหาที่ตรงไปตรงมา แต่ถ้าเราต้องการแยกบรรทัดที่มีคำว่า Jabberwock แล้วพิมพ์ส่วนที่เหลือล่ะ

เราสามารถทำได้ด้วยตัวเลือก -v (invert match) รายการนี้จะแสดงบรรทัดที่ไม่ตรงกับคำค้นหา

 grep -v "Jabberwock" jabberwocky.text 

การใช้ตัวเลือกการค้นหากลับด้าน -v กับ grep

บรรทัดที่ไม่มีคำว่า "Jabberwock" จะแสดงอยู่ในหน้าต่างเทอร์มินัล

ทุกบรรทัดที่ไม่มีคำว่า jabberwock

เราสามารถยกเว้นเงื่อนไขได้มากเท่าที่เราต้องการ มากรองบรรทัดที่มี "Jabberwock" และบรรทัดที่มี "และ" กัน เพื่อให้บรรลุสิ่งนี้ เราจะใช้ตัวเลือก -e (นิพจน์) เราจำเป็นต้องใช้มันสำหรับรูปแบบการค้นหาแต่ละแบบที่เราใช้

 grep -v -e "Jabberwock" -e "และ" jabberwocky.txt 

การใช้ประโยคค้นหาหลายคำกับ grep

จำนวนบรรทัดในผลลัพธ์จะลดลง

บรรทัดจากข้อความที่ไม่ตรงกับคำค้นหา

หากเราใช้ตัวเลือก -E (extended regexes) เราสามารถรวมรูปแบบการค้นหาด้วย “ | “ ซึ่งในบริบทนี้ไม่ได้ระบุไพพ์ แต่เป็นโอเปอเรเตอร์ OR แบบลอจิคัล

 grep -Ev "Jabberwock|และ" jabberwocky.txt 

การใช้ตัวดำเนินการตรรกะ OR กับ grep

เราได้ผลลัพธ์ที่เหมือนกันทุกประการกับคำสั่งก่อนหน้านี้ที่ยืดยาว

บรรทัดจากข้อความที่ไม่ตรงกับคำค้นหา

รูปแบบของคำสั่งจะเหมือนกันถ้าคุณต้องการใช้รูปแบบ regex แทนคำใบ้การค้นหาที่ชัดเจน คำสั่งนี้จะไม่รวมบรรทัดทั้งหมดที่ขึ้นต้นด้วยตัวอักษรใดๆ ในชุด "ACHT"

 grep -Ev "^ACHT" jabberwocky.txt 

ไม่รวมไฟล์ที่ขึ้นต้นด้วยตัวอักษรบางตัว

หากต้องการดูเส้นที่มีรูปแบบ แต่ไม่มีรูปแบบอื่น เราสามารถ grep ลงใน grep เราจะค้นหาทุกบรรทัดที่มีคำว่า "Jabberwock" จากนั้นกรองบรรทัดที่ มี คำว่า "slain" ด้วย

 grep "Jabberwock" jabberwocky.txt | grep -v "สังหาร" 

วางท่อ grep ลงใน grep เพื่อกรองสองครั้ง

ไม่รวมไฟล์

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

 grep "vorpal" verse-1.txt verse-2.txt verse-3.txt verse-4.txt verse-5.txt verse-6.txt 

ค้นหาผ่านรายการไฟล์ที่มีชื่อ

โปรดทราบว่าชื่อของไฟล์ที่มีบรรทัดที่ตรงกันจะแสดงที่จุดเริ่มต้นของแต่ละบรรทัดของเอาต์พุต

เพื่อลดการพิมพ์ เราสามารถใช้สัญลักษณ์แทนได้ แต่นั่นสามารถขัดกับสัญชาตญาณได้ ดูเหมือนว่าจะใช้งานได้

 grep "vorpal" *.txt 

การใช้สัญลักษณ์แทนเพื่อค้นหาคอลเล็กชันของไฟล์

อย่างไรก็ตาม ในไดเรกทอรีนี้มีไฟล์ TXT อื่นๆ ที่ไม่เกี่ยวข้องกับบทกวี หากเราค้นหาคำว่า "ดาบ" ด้วยโครงสร้างคำสั่งเดียวกัน เราก็จะได้รับผลบวกที่ผิดพลาดมากมาย

 grep "ดาบ" *.txt 

ค้นหา "ดาบ" ผ่านชุดไฟล์ TXT

ผลลัพธ์ที่เราต้องการถูกปกปิดโดยผลลัพธ์เท็จจำนวนมากจากไฟล์อื่นๆ ที่มีนามสกุล TXT

ชุดผลลัพธ์จำนวนมากของผลบวกลวง

คำว่า "vorpal" ไม่ตรงกับสิ่งใด แต่คำว่า "sword" รวมอยู่ในคำว่า "password" ดังนั้นจึงพบได้หลายครั้งในแฟ้มบันทึกปลอม

เราจำเป็นต้องแยกไฟล์เหล่านี้ออก ในการทำเช่นนั้น เราจะใช้ --exclude ตัวเลือก หากต้องการยกเว้นไฟล์เดียวที่เรียกว่า “vol-log-1.txt” เราจะใช้คำสั่งนี้:

 grep --exclude=vol-log-1.txt "sword" *.txt

ในกรณีนี้ เราต้องการแยกไฟล์บันทึกหลายไฟล์ที่มีชื่อขึ้นต้นด้วย "vol" ไวยากรณ์ที่เราต้องการคือ:

 grep --exclude=vol*.txt "sword" *.txt 

ไม่รวมไฟล์ที่มีสัญลักษณ์แทน

เมื่อเราใช้ตัวเลือก -R (dereference-recursive) grep จะค้นหาแผนผังไดเร็กทอรีทั้งหมดให้เรา โดยค่าเริ่มต้น มันจะค้นหาไฟล์ทั้งหมดในตำแหน่งเหล่านั้น อาจมีไฟล์หลายประเภทที่เราต้องการยกเว้น

ใต้ไดเร็กทอรีปัจจุบันของเครื่องทดสอบนี้มีไดเร็กทอรีที่ซ้อนกันซึ่งประกอบด้วยไฟล์บันทึก ไฟล์ CSV และไฟล์ MD ไฟล์ข้อความเหล่านี้เป็นไฟล์ข้อความทุกประเภทที่เราต้องการยกเว้น เราสามารถใช้ --exclude ตัวเลือกสำหรับไฟล์แต่ละประเภท แต่เราสามารถบรรลุสิ่งที่เราต้องการได้อย่างมีประสิทธิภาพมากขึ้นโดยการจัดกลุ่มประเภทไฟล์

คำสั่งนี้ไม่รวมไฟล์ทั้งหมดที่มีนามสกุล CSV หรือ MD และไฟล์ TXT ทั้งหมดที่มีชื่อขึ้นต้นด้วย "vol" หรือ "log"

 grep -R --exclude=*.{csv,md} --exclude={vol*,log*}.txt "sword" /home/dave/data/ 

ใช้หลาย --exclude ประโยคและการจัดกลุ่มชื่อไฟล์

ไม่รวมไดเรกทอรี

หากไฟล์ที่เราต้องการละเว้นอยู่ในไดเร็กทอรี และไม่มีไฟล์ในไดเร็กทอรีที่เราต้องการค้นหา เราสามารถแยกไดเร็กทอรีทั้งหมดออกได้

แนวคิดนี้คล้ายกันมากกับการยกเว้นไฟล์ ยกเว้นว่าเราใช้ตัวเลือก --exclude-dir และตั้งชื่อไดเร็กทอรีที่จะละเว้น

 grep -R --exclude-dir=backup "vorpal" /home/dave/data 

ไม่รวมไดเร็กทอรีจากการค้นหา

เราได้แยกไดเร็กทอรี "backup" ออกไปแล้ว แต่เรายังคงค้นหาผ่านไดเร็กทอรีอื่นที่เรียกว่า "backup2"

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

 grep -R --exclude-dir=backup --exclude-dir=backup2 "vorpal" /home/dave/data 

ไม่รวมสองไดเร็กทอรีจากการค้นหา

เราสามารถใช้การจัดกลุ่มได้เช่นกัน เราสามารถบรรลุสิ่งเดียวกันได้กระชับยิ่งขึ้นด้วย:

 grep -R --exclude-dir={backup,backup2} "vorpal" /home/dave/data 

ไม่รวมไดเรกทอรีที่มีการจัดกลุ่ม

คุณสามารถรวมการยกเว้นไฟล์และไดเร็กทอรีในคำสั่งเดียวกัน หากคุณต้องการแยกไฟล์ทั้งหมดออกจากไดเร็กทอรีและยกเว้นไฟล์บางประเภทจากไดเร็กทอรี ที่ ค้นหา ให้ใช้ไวยากรณ์นี้:

 grep -R --exclude=*.{csv,md} --exclude-dir=backup/archive "frumious" /home/dave/data 

ไม่รวมประเภทไฟล์และไดเร็กทอรีในคำสั่งเดียวกัน

บางครั้งมันก็เป็นสิ่งที่คุณทิ้งไป

บางครั้งเมื่อใช้ grep คุณจะรู้สึกเหมือนกำลังพยายามหาเข็มในกองหญ้า มันสร้างความแตกต่างอย่างมากในการขจัดกองหญ้าแห้ง

ที่เกี่ยวข้อง: วิธีใช้นิพจน์ทั่วไป (regexes) บน Linux