เมื่อฉันต้องการค้นหาเนื้อหาทั้งหมดฉันจะใช้ต้นไม้
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
เป็นเอกสิทธิ์ของ grep
GNU (-:
คำตอบที่ดีที่สุดย่อย: แทนที่จะท่อส่งออกของ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"