ฉันไม่แน่ใจ:
grep -r -i 'the brown dog' /*
เป็นสิ่งที่คุณหมายถึงจริงๆ นั่นหมายถึง grep ซ้ำในไฟล์และ dirs ที่ไม่ได้ซ่อนไว้/
(แต่ก็ยังดูในไฟล์และ dirs ที่ซ่อนอยู่ในนั้น)
สมมติว่าคุณหมายถึง:
grep -r -i 'the brown dog' /
สิ่งที่ควรทราบ:
grep
การปรับใช้ไม่สนับสนุน-r
ทั้งหมด และในบรรดาพฤติกรรมนั้นแตกต่างกัน: บางคนติดตาม symlinks ไปยังไดเรกทอรีเมื่อเข้าไปในแผนผังไดเรกทอรี (ซึ่งหมายความว่าคุณอาจมองหลาย ๆ ครั้งในไฟล์เดียวกันหรือแม้กระทั่งทำงานในลูปไม่ จำกัด ) บางคนจะไม่ บางตัวจะดูในไฟล์อุปกรณ์ (และใช้เวลาค่อนข้างนาน/dev/zero
) หรือไพพ์หรือไฟล์ไบนารี่ ... บางไฟล์จะไม่
- มันมีประสิทธิภาพตั้งแต่
grep
เริ่มมองหาไฟล์ภายในทันทีที่ค้นพบมัน แต่ในขณะที่ดูในไฟล์จะไม่ค้นหาไฟล์เพิ่มเติมเพื่อค้นหาอีกต่อไป (ซึ่งอาจเป็นในกรณีส่วนใหญ่)
ของคุณ:
find / -type f -exec grep -i 'the brown dog' {} \;
(ลบสิ่ง-r
ที่ไม่สมเหตุสมผลตรงนี้ออก) จะไม่มีประสิทธิภาพมากเพราะคุณใช้งานgrep
ไฟล์หนึ่งไฟล์ ;
ควรใช้สำหรับคำสั่งที่ยอมรับอาร์กิวเมนต์เดียวเท่านั้น ยิ่งกว่านั้นที่นี่เนื่องจากgrep
ดูในไฟล์เดียวมันจะไม่พิมพ์ชื่อไฟล์ดังนั้นคุณจะไม่ทราบว่าการจับคู่นั้นอยู่ที่ไหน
คุณไม่ได้มองภายในแฟ้มอุปกรณ์ท่อ symlinks ... คุณไม่ได้ดังต่อไปนี้ symlinks /proc/mem
แต่คุณยังคงอาจมองสิ่งที่อยู่ภายในเช่น
find / -type f -exec grep -i 'the brown dog' {} +
จะดีขึ้นมากเพราะgrep
คำสั่งน้อยที่สุดเท่าที่จะทำได้ คุณจะได้รับชื่อไฟล์ยกเว้นว่าการเรียกใช้ครั้งสุดท้ายมีเพียงไฟล์เดียว เพื่อที่จะดีกว่าที่จะใช้:
find / -type f -exec grep -i 'the brown dog' /dev/null {} +
หรือกับ GNU grep
:
find / -type f -exec grep -Hi 'the brown dog' {} +
โปรดทราบว่าgrep
จะไม่เริ่มต้นจนกว่าจะfind
พบไฟล์มากพอที่จะให้เคี้ยวได้ดังนั้นจะมีความล่าช้าในเบื้องต้น และfind
จะไม่ทำการค้นหาไฟล์ต่อไปจนกว่าจะgrep
มีการส่งคืนก่อนหน้า การจัดสรรและส่งผ่านรายชื่อไฟล์ขนาดใหญ่มีผลกระทบ (อาจเล็กน้อย) ดังนั้นทั้งหมดโดยรวมก็อาจจะมีประสิทธิภาพน้อยกว่ารายการgrep -r
ที่ไม่ได้ติดตาม symlink หรือดูภายในอุปกรณ์
ด้วยเครื่องมือ GNU:
find / -type f -print0 | xargs -r0 grep -Hi 'the brown dog'
ข้างต้นgrep
จะมีการเรียกใช้อินสแตนซ์น้อยที่สุดเท่าที่จะเป็นไปได้ แต่find
จะดำเนินการค้นหาไฟล์เพิ่มเติมในขณะที่การgrep
เรียกใช้ครั้งแรกนั้นอยู่ภายในแบทช์แรก นั่นอาจจะใช่หรือไม่ใช่ก็ได้ ตัวอย่างเช่นเมื่อข้อมูลที่เก็บไว้ในฮาร์ดไดรฟ์แบบหมุนได้find
และการgrep
เข้าถึงข้อมูลที่เก็บไว้ในสถานที่ต่าง ๆ บนดิสก์จะทำให้ปริมาณงานของดิสก์ช้าลงโดยทำให้หัวดิสก์เคลื่อนที่ตลอดเวลา ในการตั้งค่า RAID (ที่ไหนfind
และgrep
อาจเข้าถึงดิสก์ที่แตกต่างกัน) หรือบน SSD ซึ่งอาจสร้างความแตกต่างในเชิงบวก
ในการตั้งค่า RAID การเรียกใช้การเรียกใช้หลายรายการพร้อมกัน grep
อาจช่วยปรับปรุงสิ่งต่างๆ ยังคงมีเครื่องมือ GNU ในการจัดเก็บ RAID1 กับ 3 ดิสก์
find / -type f -print0 | xargs -r0 -P2 grep -Hi 'the brown dog'
อาจเพิ่มประสิทธิภาพอย่างมาก อย่างไรก็ตามโปรดทราบว่าไฟล์ที่สองgrep
จะเริ่มทำงานเมื่อพบไฟล์เพียงพอที่จะเติมgrep
คำสั่งแรกให้สมบูรณ์ คุณสามารถเพิ่ม-n
ตัวเลือกในxargs
การที่จะเกิดขึ้นเร็วกว่า (และส่งไฟล์น้อยลงต่อgrep
การขอร้อง)
นอกจากนี้โปรดทราบว่าหากคุณเปลี่ยนเส้นทางxargs
เอาต์พุตไปยังอุปกรณ์อื่นนอกจากอุปกรณ์เทอร์มินัลแล้วgreps
s จะเริ่มบัฟเฟอร์เอาต์พุตของพวกเขาซึ่งหมายความว่าเอาต์พุตของgrep
s เหล่านั้นอาจถูกอินเตอร์ลีลอย่างไม่ถูกต้อง คุณจะต้องใช้stdbuf -oL
(หากมีให้ใช้เช่นใน GNU หรือ FreeBSD) เพื่อแก้ปัญหานั้น (คุณอาจยังมีปัญหากับเส้นที่ยาวมาก (โดยทั่วไป> 4KiB)) หรือให้แต่ละเขียนเอาต์พุตในไฟล์แยกต่างหากและต่อกัน ทั้งหมดในที่สุด
นี่สตริงที่คุณกำลังมองหาอยู่ถาวร (ไม่ regexp) เพื่อให้ใช้-F
ตัวเลือกที่อาจจะสร้างความแตกต่าง (ไม่น่าเป็นgrep
การใช้งานทราบวิธีการเพิ่มประสิทธิภาพที่มีอยู่แล้ว)
อีกสิ่งหนึ่งที่สามารถสร้างความแตกต่างได้มากก็คือการแก้ไขโลแคลเป็น C หากคุณอยู่ในโลแคลแบบหลายไบต์:
find / -type f -print0 | LC_ALL=C xargs -r0 -P2 grep -Hi 'the brown dog'
เพื่อหลีกเลี่ยงการมองภายใน/proc
, /sys
... , ใช้-xdev
และระบุระบบไฟล์ที่คุณต้องการค้นหาใน:
LC_ALL=C find / /home -xdev -type f -exec grep -i 'the brown dog' /dev/null {} +
หรือตัดเส้นทางที่คุณต้องการแยกอย่างชัดเจน:
LC_ALL=C find / \( -path /dev -o -path /proc -o -path /sys \) -prune -o \
-type f -exec grep -i 'the brown dog' /dev/null {} +