วิธียกเว้นรูปแบบไฟล์และไดเรกทอรีด้วย grep
เผยแพร่แล้ว: 2022-06-29 ตั้งแต่ปี 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 คุณสามารถบอกให้ละเว้นรูปแบบ ไฟล์ และไดเร็กทอรีเพื่อให้ grep ดำเนินการค้นหาได้เสร็จสิ้นเร็วขึ้น และคุณไม่ได้เต็มไปด้วยผลบวกลวงที่ไม่มีความหมาย
ไม่รวมรูปแบบ
หากต้องการค้นหาด้วย grep
คุณสามารถไพพ์อินพุตจากกระบวนการอื่น เช่น cat
หรือคุณสามารถระบุชื่อไฟล์เป็นพารามิเตอร์บรรทัดคำสั่งสุดท้าย
เรากำลังใช้ไฟล์ขนาดสั้นที่มีข้อความของบทกวี Jabberwocky โดย Lewis Carroll ในสองตัวอย่างนี้ เรากำลังค้นหาบรรทัดที่ตรงกับข้อความค้นหา "Jabberwock"
cat jabberwocky.txt | grep "จาเบอร์ว็อค"
grep "Jabberwock" jabberwocky.text
บรรทัดที่ตรงกับคำใบ้การค้นหาจะแสดงรายการสำหรับเรา โดยองค์ประกอบที่ตรงกันในแต่ละบรรทัดจะเน้นด้วยสีแดง นั่นคือการค้นหาที่ตรงไปตรงมา แต่ถ้าเราต้องการแยกบรรทัดที่มีคำว่า Jabberwock แล้วพิมพ์ส่วนที่เหลือล่ะ
เราสามารถทำได้ด้วยตัวเลือก -v
(invert match) รายการนี้จะแสดงบรรทัดที่ไม่ตรงกับคำค้นหา
grep -v "Jabberwock" jabberwocky.text
บรรทัดที่ไม่มีคำว่า "Jabberwock" จะแสดงอยู่ในหน้าต่างเทอร์มินัล
เราสามารถยกเว้นเงื่อนไขได้มากเท่าที่เราต้องการ มากรองบรรทัดที่มี "Jabberwock" และบรรทัดที่มี "และ" กัน เพื่อให้บรรลุสิ่งนี้ เราจะใช้ตัวเลือก -e
(นิพจน์) เราจำเป็นต้องใช้มันสำหรับรูปแบบการค้นหาแต่ละแบบที่เราใช้
grep -v -e "Jabberwock" -e "และ" jabberwocky.txt
จำนวนบรรทัดในผลลัพธ์จะลดลง
หากเราใช้ตัวเลือก -E
(extended regexes) เราสามารถรวมรูปแบบการค้นหาด้วย “ |
“ ซึ่งในบริบทนี้ไม่ได้ระบุไพพ์ แต่เป็นโอเปอเรเตอร์ OR
แบบลอจิคัล
grep -Ev "Jabberwock|และ" jabberwocky.txt
เราได้ผลลัพธ์ที่เหมือนกันทุกประการกับคำสั่งก่อนหน้านี้ที่ยืดยาว
รูปแบบของคำสั่งจะเหมือนกันถ้าคุณต้องการใช้รูปแบบ regex แทนคำใบ้การค้นหาที่ชัดเจน คำสั่งนี้จะไม่รวมบรรทัดทั้งหมดที่ขึ้นต้นด้วยตัวอักษรใดๆ ในชุด "ACHT"
grep -Ev "^ACHT" jabberwocky.txt
หากต้องการดูเส้นที่มีรูปแบบ แต่ไม่มีรูปแบบอื่น เราสามารถ grep
ลงใน grep
เราจะค้นหาทุกบรรทัดที่มีคำว่า "Jabberwock" จากนั้นกรองบรรทัดที่ มี คำว่า "slain" ด้วย
grep "Jabberwock" jabberwocky.txt | grep -v "สังหาร"
ไม่รวมไฟล์
เราสามารถขอให้ 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
คำว่า "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-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