ฉันกำลังใช้งานfind
และรับรายการไฟล์ที่ฉันต้องการgrep
ผ่าน ฉันจะไพพ์รายชื่อนั้นได้grep
อย่างไร?
ฉันกำลังใช้งานfind
และรับรายการไฟล์ที่ฉันต้องการgrep
ผ่าน ฉันจะไพพ์รายชื่อนั้นได้grep
อย่างไร?
คำตอบ:
กรณีทั่วไปที่ทำงานกับคำสั่งใด ๆ ที่เขียนไปยัง stdout คือการใช้xargs
ซึ่งจะช่วยให้คุณแนบอาร์กิวเมนต์บรรทัดคำสั่งจำนวนเท่าใดก็ได้ที่ส่วนท้ายของคำสั่ง:
$ find … | xargs grep 'search'
หรือเพื่อฝังคำสั่งในgrep
บรรทัดของคุณด้วย backticks หรือ$()
ซึ่งจะรันคำสั่งและแทนที่ผลลัพธ์:
$ grep 'search' $(find …)
โปรดทราบว่าคำสั่งเหล่านี้จะไม่ทำงานหากชื่อไฟล์มีช่องว่างหรือ“ อักขระแปลก ๆ ” อื่น ๆ ( \'"
สำหรับ xargs \[*?
สำหรับ$(find …)
)
อย่างไรก็ตามในกรณีเฉพาะของfind
ความสามารถในการเรียกใช้โปรแกรมบนอาร์กิวเมนต์ที่กำหนดนั้นมีอยู่แล้วภายใน:
$ find … -exec grep 'search' {} \;
ทุกสิ่งระหว่าง-exec
และ;
เป็นคำสั่งให้ดำเนินการ; จะถูกแทนที่ด้วยชื่อไฟล์ที่พบโดย{}
find
ที่จะดำเนินการแยกต่างหากgrep
สำหรับแต่ละไฟล์ เนื่องจากgrep
สามารถใช้ชื่อไฟล์จำนวนมากและค้นหาพวกเขาทั้งหมดคุณสามารถเปลี่ยน;
เพื่อ+
ที่จะบอกหาที่จะผ่านทั้งหมดชื่อไฟล์ที่ตรงกันไปgrep
ในครั้งเดียว:
$ find … -exec grep 'search' {} \+
find ... -type f -print0 | xargs -r0 grep 'search' /dev/null
ฉันชอบ QED ในขณะที่-exec +
มีประสิทธิภาพมากมันไม่ได้มีอยู่ในทุกรุ่นของการค้นหา
$ find … -exec grep 'search' {} \+
รูปแบบเป็นมากเร็วที่สุด
บางรุ่นของgrep
(เช่นบน Linux หรือBSDหรือ Mac OS X ที่ไม่ได้ฝังตัว) มี-r
ตัวเลือกเพื่อทำการค้นหาแบบเรียกซ้ำ บน OpenBSD ใช้-R
(และไม่มี--exclude
ตามตัวอย่างด้านล่าง) นี้ครอบคลุมถึงชุดที่เรียบง่ายของด้วยfind
grep
หากการดำเนินการของคุณไม่ได้มี-R
ธงหรือถ้าคุณต้องการเกณฑ์ไฟล์จับคู่นักเล่น, คุณสามารถใช้-exec
หลักของการที่จะทำให้มันรันfind
grep
การfind
ใช้งานรุ่นเก่าบางอย่างไม่สนับสนุน-exec
... +
; ในระบบเหล่านี้ใช้;
แทน+
(จะเรียกgrep
หนึ่งครั้งต่อไฟล์ดังนั้นมันจะช้าลง แต่ไม่เช่นนั้นผลลัพธ์จะเหมือนกัน) สังเกต/dev/null
เคล็ดลับที่จะทำให้grep
ชื่อไฟล์แม้ว่ามันจะเกิดขึ้นกับไฟล์เดียว (GNU grep และ FreeBSD / NetBSD / OSX grep มี-H
ตัวเลือกเพื่อให้ได้ผลเหมือนกัน)
find . -type f -name '*.o' -prune -o -exec grep 'needle' /dev/null {} +
grep -r --exclude='*.o' 'needle' .
GNU grep
มี-H
ตัวเลือกให้พิมพ์ชื่อไฟล์เสมอ