ทางเลือกอื่นที่เร็วกว่าสำหรับ "ค้นหา" และ "ค้นหา"?


22

ฉันต้องการใช้ "ค้นหา" และค้นหา "เพื่อค้นหาไฟล์ต้นฉบับในโครงการของฉัน แต่ใช้เวลานานในการรันมีทางเลือกอื่นที่เร็วกว่าสำหรับโปรแกรมเหล่านี้ที่ฉันไม่รู้จักหรือวิธีเพิ่มประสิทธิภาพ ของโปรแกรมเหล่านี้


2
locateควรมีจำนวนมากอย่างรวดเร็วโดยพิจารณาว่าจะใช้ดัชนีที่สร้างไว้ล่วงหน้า (ข้อควรระวังหลักที่จำเป็นต้องได้รับการปรับปรุงให้ทันสมัย) ในขณะที่findต้องอ่านรายชื่อไดเรกทอรี
afrazier

2
คุณกำลังค้นหาตำแหน่งใดอยู่ mlocate เร็วกว่า slocate ในระยะยาว (โปรดทราบว่าแพคเกจใดที่คุณติดตั้งคำสั่งยังคงอยู่ดังนั้นให้ตรวจสอบแพ็คเกจผู้จัดการของคุณ)
Paul

@benhsu เมื่อฉันเรียกใช้find /usr/src -name fprintf.cบนเครื่องเดสก์ท็อป OpenBSD ของฉันมันจะส่งคืนตำแหน่งของไฟล์ต้นฉบับเหล่านั้นในเวลาน้อยกว่า 10 วินาที locate fprintf.c | grep '^/usr/src.*/fprintf.c$'กลับมาในไม่กี่วินาที คำจำกัดความของ "เวลาในการทำงานนาน" คืออะไรและคุณใช้findและlocateอย่างไร?
Kusalananda

@ พอลฉันใช้ mlocate
benhsu

@KAK ฉันต้องการใช้ผลลัพธ์การค้นหา / ตำแหน่งเพื่อเปิดไฟล์ใน emacs กรณีการใช้งานที่ฉันมีอยู่ในใจคือฉันต้องการแก้ไขไฟล์ฉันพิมพ์ชื่อไฟล์ (หรือบาง regexp จับคู่ชื่อไฟล์) เป็น emacs และ emacs จะใช้ find / locate เพื่อแสดงรายการของไฟล์ที่ตรงกับมัน ดังนั้นฉันจะชอบเวลาตอบสนองเร็วพอที่จะโต้ตอบ (น้อยกว่า 1 วินาที) ฉันมีไฟล์ประมาณ 3 ล้านไฟล์ใน $ HOME สิ่งหนึ่งที่ฉันทำได้คือทำให้คำสั่ง find ตัดออกบางไฟล์
benhsu

คำตอบ:


16

ค้นหาไฟล์ต้นฉบับในโครงการ

ใช้คำสั่งที่ง่ายกว่า

โดยทั่วไปแหล่งที่มาสำหรับโครงการน่าจะอยู่ในที่เดียวอาจอยู่ในไดเรกทอรีย่อยไม่กี่ซ้อนกันไม่เกินสองหรือสามลึกดังนั้นคุณสามารถใช้คำสั่งที่เร็วขึ้น (อาจจะ) เช่น

(cd /path/to/project; ls *.c */*.c */*/*.c)

ใช้ประโยชน์จากข้อมูลเมตาของโครงการ

ในโครงการ C คุณมักจะมี Makefile ในโครงการอื่นคุณอาจมีสิ่งที่คล้ายกัน สิ่งเหล่านี้อาจเป็นวิธีที่รวดเร็วในการแยกรายการไฟล์ (และตำแหน่งที่ตั้ง) เขียนสคริปต์ที่ใช้ประโยชน์จากข้อมูลนี้เพื่อค้นหาไฟล์ ฉันมี "แหล่ง" grep variable $(sources programname)สคริปต์เพื่อที่ฉันสามารถเขียนคำสั่งเช่น

เร่งค้นหา

ค้นหาสถานที่น้อยลงแทนที่จะfind / …ใช้ในfind /path/to/project …ที่ที่เป็นไปได้ ลดความซับซ้อนของเกณฑ์การเลือกให้มากที่สุด ใช้ท่อเพื่อเลื่อนเกณฑ์การเลือกบางอย่างหากมีประสิทธิภาพมากขึ้น

นอกจากนี้คุณสามารถ จำกัด ความลึกของการค้นหา สำหรับฉันมันช่วยเพิ่มความเร็วในการ 'ค้นหา' ได้มาก คุณสามารถใช้สวิตช์ -maxdepth ตัวอย่างเช่น '-maxdepth 5'

เร่งค้นหา

ตรวจสอบให้แน่ใจว่าได้จัดทำดัชนีตำแหน่งที่คุณสนใจอ่านหน้าคนและใช้ประโยชน์จากตัวเลือกที่เหมาะสมกับงานของคุณ

   -U <dir>
          Create slocate database starting at path <dir>.

   -d <path>
          --database=<path> Specifies the path of databases to search  in.


   -l <level>
          Security  level.   0  turns  security checks off. This will make
          searchs faster.   1  turns  security  checks  on.  This  is  the
          default.

ลบความจำเป็นในการค้นหา

บางทีคุณกำลังค้นหาเพราะคุณลืมสิ่งที่เป็นหรือไม่ได้บอก ในกรณีก่อนหน้าเขียนบันทึก (เอกสาร) ในกรณีหลังถาม? อนุสัญญามาตรฐานและความสม่ำเสมอสามารถช่วยได้มาก


10

ฉันใช้ส่วน "เร่งความเร็วค้นหา" ของคำตอบของ RedGrittyBrick ฉันสร้าง db ที่เล็กลง:

updatedb -o /home/benhsu/ben.db -U /home/benhsu/ -e "uninteresting/directory1 uninteresting/directory2"

แล้วชี้ไปlocateที่มัน:locate -d /home/benhsu/ben.db


6

ชั้นเชิงที่ฉันใช้คือใช้-maxdepthตัวเลือกกับfind:

find -maxdepth 1 -iname "*target*"

ทำซ้ำกับความลึกที่เพิ่มขึ้นจนกว่าคุณจะพบสิ่งที่คุณกำลังมองหาหรือคุณเบื่อที่จะมอง การทำซ้ำสองสามครั้งแรกมีแนวโน้มที่จะกลับมาทันที

สิ่งนี้ทำให้มั่นใจได้ว่าคุณจะไม่เสียเวลาในการค้นหาความลึกของต้นไม้ใหญ่เมื่อสิ่งที่คุณกำลังมองหาอยู่ใกล้กับฐานของลำดับชั้น


นี่คือตัวอย่างสคริปต์เพื่อทำให้กระบวนการนี้เป็นอัตโนมัติ (Ctrl-C เมื่อคุณเห็นสิ่งที่คุณต้องการ):

(
TARGET="*target*"
for i in $(seq 1 9) ; do
   echo "=== search depth: $i"
   find -mindepth $i -maxdepth $i -iname "$TARGET"
done
echo "=== search depth: 10+"
find -mindepth 10 -iname $TARGET
)

โปรดทราบว่าความซ้ำซ้อนโดยธรรมชาติที่เกี่ยวข้อง (แต่ละรอบจะต้องผ่านโฟลเดอร์ที่ประมวลผลในรอบก่อนหน้า) จะได้รับการปรับให้เหมาะสมที่สุดผ่านการแคชดิสก์

เหตุใดจึงไม่มีfindลำดับการค้นหานี้เป็นคุณลักษณะในตัว อาจเป็นเพราะมันมีความซับซ้อน / เป็นไปไม่ได้ที่จะนำไปใช้ถ้าคุณคิดว่าการสำรวจเส้นทางที่ซ้ำซ้อนนั้นไม่เป็นที่ยอมรับ การมีอยู่ของ-depthตัวเลือกจะบอกใบ้ถึงความเป็นไปได้ แต่อนิจจา ...


1
... จึงทำการค้นหา "ความกว้าง - แรก"
nobar

3

ทางออกที่ง่ายอีกวิธีหนึ่งคือการใช้การขยายวงกลมแบบใหม่ การเปิดใช้งาน:

  • bash: shopt -s globstar
  • ksh: ตั้งค่า -o globstar
  • zsh: เปิดใช้งานแล้ว

จากนั้นคุณสามารถเรียกใช้คำสั่งเช่นนี้ได้ในไดเรกทอรีแหล่งข้อมูลระดับบนสุด:

# grep through all c files
grep printf **/*.c

# grep through all files
grep printf ** 2>/dev/null

นี่เป็นข้อได้เปรียบที่ค้นหาซ้ำทุกไดเรกทอรีย่อยและรวดเร็วมาก


3

ผู้ค้นหาเงิน

คุณอาจพบว่ามีประโยชน์สำหรับการค้นหาเนื้อหาของซอร์สโค้ดจำนวนมากอย่างรวดเร็ว ag <keyword>เพียงพิมพ์ นี่คือผลลัพธ์ของฉันapt show silversearcher-ag:

ฉันมักจะใช้กับ:

-G --file-search-regex PATTERN ค้นหาเฉพาะไฟล์ที่มีชื่อตรงกับ PATTERN

ag -G "css$" important

ภาพหน้าจอ


1
ripgrep ของ algorythm ถูกกล่าวหาว่าเร็วกว่า silversearch และก็ยังได้รับเกียรตินิยม.gitignoreไฟล์และข้าม.git, .svn, .hg.. โฟลเดอร์
ccpizza

@ccpizza งั้นเหรอ? Silver Searcherยังให้เกียรติ.gitignoreและละเว้นไฟล์ที่ซ่อนอยู่และไบนารีโดยค่าเริ่มต้น ยังมีผู้ร่วมให้ข้อมูลเพิ่มมากขึ้นมีดาวบน Github มากขึ้น (14700 vs 8300) และมีอยู่แล้วใน repos ของ distros นายกเทศมนตรี โปรดระบุการเปรียบเทียบแหล่งข้อมูลบุคคลที่สามที่เชื่อถือได้ที่ได้รับการอัปเดต อย่างไรก็ตามripgrepดูเหมือนว่าเป็นซอฟต์แวร์ที่ยอดเยี่ยม
Pablo

ดีแล้วที่รู้! ฉันไม่ได้มีส่วนเกี่ยวข้องกับผู้แต่งripgrepแต่อย่างใดมันก็พอดีกับความต้องการของฉันดังนั้นฉันจึงหยุดค้นหาตัวเลือกอื่น ๆ
ccpizza

ผู้ค้นหาเงิน.gitignoreก็เคารพเช่นกัน ที่กล่าวว่าrgเป็นที่น่าอัศจรรย์อย่างแน่นอน ก่อนอื่นก็มีการสนับสนุน Unicode จากประสบการณ์ของฉันrgอย่างรวดเร็วอย่างน้อยสองครั้งอย่างต่อเนื่องag(YMMV) ฉันคิดว่ามันเป็นเพราะโปรแกรมแยกวิเคราะห์ regex ของ Rust ซึ่งเห็นได้ชัดว่ายังไม่พร้อมในช่วงหลายปีที่ผ่านมาagเป็นเรื่องใหม่ rgสามารถให้ผลลัพธ์ที่กำหนดได้ (แต่ไม่ได้โดยค่าเริ่มต้น) มันสามารถขึ้นบัญชีดำประเภทไฟล์ที่agสามารถขึ้นบัญชีขาวได้เท่านั้นสามารถละเว้นไฟล์ได้ตามขนาด (ลาก่อนบันทึก) ฉันยังคงใช้agในกรณีที่ฉันต้องการการจับคู่แบบหลายบรรทัดซึ่งrgไม่สามารถทำได้
Pellmeister

2

สำหรับทดแทนการค้นหาตรวจสอบFD มันมีอินเตอร์เฟสที่ใช้งานง่ายกว่าและง่ายกว่าคำสั่ง find ต้นฉบับและค่อนข้างเร็วกว่าเล็กน้อย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.