เมื่อฉันต้องการค้นหาเนื้อหาทั้งหมดฉันจะใช้ต้นไม้
find . -type f -print0 | xargs -0 grep <search_string>
มีวิธีที่ดีกว่าในการทำเช่นนี้ในแง่ของประสิทธิภาพหรือความกะทัดรัด?
เมื่อฉันต้องการค้นหาเนื้อหาทั้งหมดฉันจะใช้ต้นไม้
find . -type f -print0 | xargs -0 grep <search_string>
มีวิธีที่ดีกว่าในการทำเช่นนี้ในแง่ของประสิทธิภาพหรือความกะทัดรัด?
คำตอบ:
ตรวจสอบว่าคุณgrepสนับสนุน-rตัวเลือก (สำหรับrecurse ):
grep -r <search_string> .
--exclude-dirที่อยู่ประสิทธิภาพและเรามีผู้ชนะ!
grepใน FreeBSD และ Linux distros ล่าสุดสนับสนุน แล้วทำไม--exclude-dirล่ะ? คุณไม่ได้ขอให้ค้นหาต้นไม้ทั้งต้นใช่ไหม
--exclude-dirมีประโยชน์จริง ๆ ในกรณีการใช้งานของฉัน (เนื่องจากส่วนย่อยของต้นไม้มีขนาดใหญ่ แต่ไร้ประโยชน์) และฉันถามเกี่ยวกับประสิทธิภาพ ... แต่คุณพูดถูกมันไม่จำเป็น
--exclude-dirเป็นเอกสิทธิ์ของ grepGNU (-:
คำตอบที่ดีที่สุดย่อย: แทนที่จะท่อส่งออกของfindเข้าgrepคุณสามารถเรียกใช้เพียง
find . -type f -exec grep 'research' {} '+'
และ voila คำสั่งเดียวแทนที่จะเป็นสองคำสั่ง!
คำอธิบาย:
find . -type f
ค้นหาไฟล์ปกติทั้งหมดภายใน
-exec grep 'research'
grep 'การวิจัย'
{}
ในชื่อไฟล์ที่พบ
'+'
ใช้หนึ่งคำสั่งต่อชื่อไฟล์ทั้งหมดไม่ใช่หนึ่งครั้งต่อชื่อไฟล์
Nb: ด้วย';'ชื่อไฟล์ต่อหนึ่งครั้ง
นอกเหนือจากนั้นหากคุณใช้ในการประมวลผลซอร์สโค้ดคุณอาจมองเข้าไปackซึ่งทำเพื่อค้นหาบิตรหัสได้อย่างง่ายดาย
แก้ไข:
คุณสามารถขยายการวิจัยออกไปเล็กน้อย ก่อนอื่นคุณสามารถใช้-name ''สวิตช์ของfindเพื่อค้นหาไฟล์ที่มีรูปแบบการตั้งชื่อแบบเฉพาะเจาะจง
ตัวอย่างเช่น
ไฟล์ที่สอดคล้องกับบันทึกเท่านั้น: -name '*.log'
เฉพาะไฟล์ที่ตรงกับส่วนหัว c แต่คุณไม่สามารถใช้ตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็กสำหรับส่วนขยายชื่อไฟล์ของคุณ: -iname *.c
หมายเหตุ: เหมือนgrepและackที่-iสวิทช์หมายถึงกรณีตายในกรณีนี้
ในกรณีนั้น grep จะแสดงโดยไม่มีสีและไม่มีหมายเลขบรรทัด
คุณสามารถเปลี่ยนได้ด้วย--colorและ-nสวิตช์ (สีและหมายเลขบรรทัดในไฟล์ตามลำดับ)
ในท้ายที่สุดคุณสามารถมีสิ่งต่อไปนี้:
find . -name '*.log' -type f -exec grep --color -n 'pattern' {} '+'
เช่น
$ find . -name '*.c' -type f -exec grep -n 'hello' {} '+'
./test2/target.c:1:hello
-name '*.log'นี้มากกว่าเพราะเร็วกว่า
หากคุณต้องการเรียกเก็บเงินคืนในไดเรกทอรีย่อย:
grep -R 'pattern' .
-Rตัวเลือกที่ไม่ได้เป็นตัวเลือกมาตรฐาน แต่ได้รับการสนับสนุนโดยส่วนใหญ่ที่พบบ่อยgrepการใช้งาน
-rแทน-Rการข้าม symlink เมื่อ grep GNU เกี่ยวข้อง
grepการใช้งานของGNU ในปัจจุบันจะเป็นแบบเรียกซ้ำฉันคิดว่า มิฉะนั้นจะขึ้นอยู่กับความหมายของ "ต้นไม้"
grepควรทำ หากผู้ใช้มีการเชื่อมโยงสัญลักษณ์ในโครงสร้างไดเรกทอรีของพวกเขานั่นคือปัญหาของผู้ใช้ :-)
/sys/devices/cpu/subsystem/devices/cpu/subsystem/devices/cpu/...(-XI เหมือนเครื่องมือดูแลเด็ก ๆ (เว้นแต่พวกเขาจะใช้เวทย์มนตร์แปลก ๆ ที่พวกเขาเรียกว่า "AI") (-;
ตามที่ระบุไว้ข้างต้น-rหรือ-R(ขึ้นอยู่กับการจัดการ symlink ที่ต้องการ) เป็นตัวเลือกที่รวดเร็ว
อย่างไรก็ตาม-d <action>อาจมีประโยชน์ในบางครั้ง
สิ่งที่ดีเกี่ยวกับ-dคือคำสั่ง skip ซึ่งเงียบ "grep: directory_name: Is a directory" เมื่อคุณเพียงแค่ต้องการสแกนระดับปัจจุบัน
$ grep foo *
grep: q2: Is a directory
grep: rt: Is a directory
$ grep -d skip foo *
$
และแน่นอน:
$ grep -d recurse foo *
(list of results that don't exist because the word foo isn't in our source code
and I wouldn't publish it anyway).
$
ตัวเลือกที่เป็นประโยชน์จริงๆภายในสคริปต์อื่นดังนั้นคุณจึงไม่ต้อง-d skip 2> /dev/null:)
หากคุณจัดการกับไฟล์จำนวนมาก grep จะทำงานเร็วขึ้นหากคุณตัดไฟล์ที่จำเป็นต้องค้นหาลงไปแทนที่จะทำการ grepping ไฟล์ทั้งหมดในโฟลเดอร์ย่อย
ฉันใช้รูปแบบนี้บางครั้ง:
grep "primary" `find . | grep cpp$`
ค้นหาไฟล์ทั้งหมดในโฟลเดอร์ย่อยของ.จุดสิ้นสุดcppนั้น จากนั้น grep ไฟล์เหล่านั้นสำหรับ "หลัก"
หากคุณต้องการคุณสามารถทำการต่อท่อผลลัพธ์เหล่านั้นไปยังการโทร grep เพิ่มเติม:
grep "primary" `find . | grep cpp$` | grep -v "ignoreThis" | grep -i "caseInsensitiveGrep"