Alternatif lebih cepat untuk "menemukan" dan "mencari"?

22

Saya ingin menggunakan "temukan" dan temukan "untuk mencari file sumber di proyek saya, tetapi mereka membutuhkan waktu lama untuk dijalankan. Apakah ada alternatif yang lebih cepat untuk program ini yang tidak saya ketahui, atau cara untuk mempercepat kinerja program-program ini?

benhsu
sumber
2
locateseharusnya sudah banyak cepat, mengingat itu menggunakan indeks pra-dibangun (peringatan utama adalah bahwa itu harus tetap up to date), sementara findharus membaca daftar direktori.
afrazier
2
Lokasi mana yang Anda gunakan? mlocate lebih cepat daripada slocate dengan cara yang panjang (perhatikan bahwa paket mana pun yang telah Anda instal, perintahnya masih dapat ditemukan, jadi periksalah manajer paket Anda)
Paul
@ benhsu, ketika saya menjalankan find /usr/src -name fprintf.cmesin desktop OpenBSD saya, ia mengembalikan lokasi file sumber tersebut dalam waktu kurang dari 10 detik. locate fprintf.c | grep '^/usr/src.*/fprintf.c$'kembali di bawah satu detik. Apa definisi Anda tentang "waktu yang lama untuk menjalankan" dan bagaimana Anda menggunakan finddan locate?
Kusalananda
@ Paul, saya menggunakan mlocate.
benhsu
@ Kak, saya ingin menggunakan output dari temukan / temukan untuk membuka file di emacs. use case yang ada dalam pikiran saya adalah, saya ingin mengedit file, saya ketik nama file (atau regexp yang cocok dengan nama file) ke dalam emacs, dan emacs akan menggunakan find / temukan untuk membuka daftar file yang cocok dengan itu, jadi saya akan menyukai waktu respon yang cukup cepat untuk menjadi interaktif (di bawah 1 detik). Saya memiliki sekitar 3 juta file dalam $ HOME, satu hal yang dapat saya lakukan adalah membuat perintah find saya memangkas beberapa file.
benhsu

Jawaban:

16

Mencari file sumber dalam suatu proyek

Gunakan perintah yang lebih sederhana

Secara umum, sumber untuk suatu proyek kemungkinan berada di satu tempat, mungkin di beberapa subdirektori bersarang tidak lebih dari dua atau tiga dalam, sehingga Anda dapat menggunakan (mungkin) perintah yang lebih cepat seperti

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

Manfaatkan metadata proyek

Dalam proyek C Anda biasanya memiliki Makefile. Dalam proyek lain, Anda mungkin memiliki sesuatu yang serupa. Ini bisa menjadi cara cepat untuk mengekstrak daftar file (dan lokasi mereka) menulis skrip yang memanfaatkan informasi ini untuk mencari file. Saya memiliki skrip "sumber" sehingga saya dapat menulis perintah seperti grep variable $(sources programname).

Mempercepat menemukan

Cari lebih sedikit tempat, alih-alih find / …gunakan find /path/to/project …jika memungkinkan. Sederhanakan kriteria seleksi sebanyak mungkin. Gunakan pipa untuk menunda beberapa kriteria pemilihan jika itu lebih efisien.

Anda juga dapat membatasi kedalaman pencarian. Bagi saya, ini meningkatkan kecepatan 'menemukan' banyak. Anda dapat menggunakan sakelar -maxdepth. Misalnya '-maxdepth 5'

Mempercepat lokasi

Pastikan itu mengindeks lokasi yang Anda minati. Baca halaman manual dan manfaatkan opsi apa pun yang sesuai dengan tugas Anda.

   -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.

Hapus kebutuhan untuk mencari

Mungkin Anda mencari karena Anda lupa di mana sesuatu itu atau tidak diberitahu. Dalam kasus sebelumnya, tulis catatan (dokumentasi), dalam kasus terakhir, tanyakan? Konvensi, standar, dan konsistensi dapat banyak membantu.

RedGrittyBrick
sumber
10

Saya menggunakan bagian "mempercepat lokasi" dari jawaban RedGrittyBrick. Saya membuat db lebih kecil:

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

lalu menunjuk locateitu:locate -d /home/benhsu/ben.db

benhsu
sumber
6

Taktik yang saya gunakan adalah menerapkan -maxdepthopsi dengan find:

find -maxdepth 1 -iname "*target*"

Ulangi dengan kedalaman yang lebih dalam sampai Anda menemukan apa yang Anda cari, atau Anda bosan melihatnya. Beberapa iterasi pertama cenderung kembali secara instan.

Ini memastikan bahwa Anda tidak membuang waktu di muka melihat melalui kedalaman sub-pohon besar ketika apa yang Anda cari cenderung berada di dekat pangkal hierarki.


Berikut ini contoh skrip untuk mengotomatiskan proses ini (Ctrl-C ketika Anda melihat apa yang Anda inginkan):

(
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
)

Perhatikan bahwa redundansi bawaan yang terlibat (setiap pass harus melintasi folder yang diproses pada pass sebelumnya) sebagian besar akan dioptimalkan jauh melalui cache disk.

Mengapa tidak findmencari pesanan ini sebagai fitur bawaan? Mungkin karena itu akan rumit / tidak mungkin untuk diterapkan jika Anda berasumsi bahwa traversal yang berlebihan tidak dapat diterima. Adanya -depthopsi mengisyaratkan kemungkinan, tapi sayangnya ...

bangsawan
sumber
1
... dengan demikian melakukan pencarian "luas pertama".
nobar
3

Solusi mudah lainnya adalah dengan menggunakan globbing shell diperpanjang yang baru. Untuk mengaktifkan:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: sudah diaktifkan

Kemudian, Anda dapat menjalankan perintah seperti ini di direktori sumber tingkat atas:

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

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

Ini memiliki keuntungan yang dicari secara rekursif melalui semua subdirektori dan sangat cepat.

dannyw
sumber
3

Pencari Perak

Anda mungkin menemukan itu berguna untuk mencari dengan sangat cepat konten dari sejumlah besar file kode sumber. Cukup ketik ag <keyword>. Berikut beberapa output dari saya apt show silversearcher-ag:

Saya biasanya menggunakannya dengan:

-G --file-search-regex PATTERN Hanya mencari file yang namanya cocok dengan POLA.

ag -G "css$" important

tangkapan layar

Pablo A
sumber
1
yang ripgrep ini algorythm diduga lebih cepat dari silversearch, dan juga menghormati .gitignorefile dan melompat .git, .svn, .hg.. folder.
ccpizza
@ccpizza Jadi? Penelusur Perak juga menghormati .gitignoredan mengabaikan file tersembunyi dan biner secara default. Juga memiliki lebih banyak kontributor, lebih banyak bintang di Github (14700 vs 8300) dan sudah ada di repo walikota. Harap berikan perbandingan sumber pihak ketiga yang dapat diperbarui dan dapat diperbarui. Meskipun demikian, ripgreptampak perangkat lunak yang hebat.
Pablo A
senang mendengarnya! Saya tidak berafiliasi dengan penulis ripgrepdalam cara apa pun, itu hanya sesuai dengan kebutuhan saya, jadi saya berhenti mencari opsi lain.
ccpizza
Pencari perak .gitignorejuga menghormati . Yang mengatakan, rgbenar-benar luar biasa. Pertama, ia memiliki dukungan unicode. Dalam pengalaman saya rgsecara konsisten setidaknya dua kali lebih cepat ag(YMMV), saya kira itu karena parser regex Rust, yang jelas belum siap namun pada tahun-tahun agyang baru itu baru. rgdapat memberikan output deterministik (tetapi tidak secara default), ia dapat membuat daftar hitam jenis file yang aghanya dapat memasukkan daftar putih, dapat mengabaikan file berdasarkan ukuran (bye bye logs). Saya masih menggunakan agkalau-kalau saya perlu pencocokan multiline, yang rgtidak bisa dilakukan.
The Pellmeister
2

Untuk mencari pengganti, lihat fd . Ini memiliki antarmuka yang lebih sederhana / lebih intuitif daripada perintah find asli, dan sedikit lebih cepat.

Keith Hughitt
sumber