"Bul" ve "bul" için daha hızlı alternatifler?


22

Projemdeki kaynak dosyaları aramak için "bul" ve bul "işlevini kullanmak isteyeceğim, ancak çalıştırılması uzun zaman alıyor. Bilmediğim bu programlara daha hızlı alternatifler veya performansı hızlandırmanın yolları var mı? bu programlar?


2
locateönceden oluşturulmuş bir dizin (güncel tutulması gereken birincil uyarı) findkullandığını ve dizin listelerini okuması gerektiğini düşünerek zaten çok hızlı olmalıdır .
afrazier

2
Hangi yeri kullanıyorsunuz? mlocate, uzun bir yoldan slocate'den daha hızlıdır (hangi paketi yüklediyseniz, komutun hala bulunacağına dikkat edin, bu nedenle paket yöneticinizi kontrol edin)
Paul

@benhsu, find /usr/src -name fprintf.cOpenBSD masaüstü bilgisayarımda çalıştığımda, bu kaynak dosyaların konumlarını 10 saniyeden daha kısa sürede döndürüyor. locate fprintf.c | grep '^/usr/src.*/fprintf.c$'bir saniyenin altında geri gelir. Ve nasıl kullanılır "çalıştırmayı uzun süre" tanımınız nedir findve locate?
Kusalananda

@ Paul, mlocate kullanıyorum.
benhsu

@KAK, emacs içinde bir dosyayı açmak için find / locate çıktısını kullanmak istiyorum. aklımdaki kullanım örneği, dosyayı düzenlemek istiyorum, emacs içine dosya adını (veya dosya adıyla eşleşen bazı regexp) yazıyorum ve emacs, dosya ile eşleşen dosyaların listesini getirmek için find / locate kullanacak, bu yüzden yanıt süresini interaktif olacak kadar hızlı seveceğim (1 saniyenin altında). $ HOME'da yaklaşık 3 milyon dosyam var, yapabileceğim bir şey, find komutumu bazı dosyaların budanması.
benhsu

Yanıtlar:


16

Bir projedeki kaynak dosyaları arama

Daha basit bir komut kullanın

Genel olarak, bir projenin kaynağının bir yerde olması muhtemeldir, belki de iki veya üçten fazla derinliğe yerleştirilmemiş birkaç alt dizinde olabilir, böylece (muhtemelen) daha hızlı bir komut kullanabilirsiniz.

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

Proje meta verilerini kullanma

Bir C projesinde tipik olarak bir Makefile'niz olur. Diğer projelerde de benzer bir şey olabilir. Bunlar, dosyaları bulmak için bu bilgileri kullanan bir komut dosyası yazmak için dosyaların listesini (ve konumlarını) ayıklamanın hızlı bir yolu olabilir. Gibi komutlar yazabilmek için bir "kaynaklar" komut dosyası var grep variable $(sources programname).

Bulmayı hızlandırmak

Mümkün olan yerlerde find / …kullanmak yerine daha az yer arayın find /path/to/project …. Seçim ölçütlerini olabildiğince basitleştirin. Daha verimli ise bazı seçim ölçütlerini ertelemek için boru hatlarını kullanın.

Ayrıca, arama derinliğini sınırlayabilirsiniz. Benim için bu, 'bulma' hızını çok artırıyor. -Maxdepth anahtarını kullanabilirsiniz. Örneğin '-maksuppth 5'

Hızlandırın bulun

İlgilendiğiniz yerleri dizine eklediğinden emin olun. Man sayfasını okuyun ve görevinize uygun seçenekleri kullanın.

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

Arama ihtiyacını ortadan kaldırın

Belki arama yapıyorsunuz çünkü bir şeyin nerede söylendiğini veya söylenmediğini unuttunuz. İlk durumda, ikincisine notlar (belgeler) yazın, sormak ister misiniz? Sözleşmeler, standartlar ve tutarlılık çok yardımcı olabilir.


10

RedGrittyBrick'in cevabının "hızlandır" yerini kullandım. Daha küçük bir db oluşturdum:

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

sonra işaret locateetti:locate -d /home/benhsu/ben.db


6

Kullandığım bir taktik -maxdepthseçeneği şu şekilde uygulamaktır find:

find -maxdepth 1 -iname "*target*"

Aradığınızı bulana veya bakmaktan yorulana kadar artan derinliklerle tekrarlayın. İlk birkaç iterasyonun anında geri dönmesi muhtemeldir.

Bu, aradığınız şeyin hiyerarşinin tabanına yakın olma olasılığı daha yüksek olduğunda, devasa alt ağaçların derinliklerine bakarak ön zaman kaybetmemenizi sağlar.


Bu işlemi otomatikleştirmek için örnek bir komut dosyası (ne istediğinizi gördüğünüzde 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
)

İlgili doğal yedekliliğin (her geçişin önceki geçişlerde işlenen klasörleri çaprazlamak zorunda kalacağı) büyük ölçüde disk önbelleğe alma yoluyla optimize edileceğini unutmayın.

Neden findbu arama sırası yerleşik bir özellik olarak sunulmuyor? Belki de gereksiz geçişin kabul edilemez olduğunu varsayarsanız uygulanması karmaşık / imkansız olacaktır. -depthSeçeneğin varlığı olasılığa işaret ediyor, ama ne yazık ki ...


1
... böylece "önce genişlik" araması yapıyor.
nobar

3

Başka bir kolay çözüm, daha yeni uzatılmış kabuk globbing kullanmaktır. Etkinleştirmek:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: zaten etkin

Ardından, üst düzey kaynak dizinde aşağıdaki gibi komutları çalıştırabilirsiniz:

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

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

Bu, tüm alt dizinlerde özyinelemeli olarak arama yapma avantajına sahiptir ve çok hızlıdır.


3

Gümüş Arayıcı

Çok sayıda kaynak kodu dosyasının içeriğini çok hızlı aramak için yararlı bulabilirsiniz . Sadece yazın ag <keyword>. İşte benim çıktı bazı apt show silversearcher-ag:

Ben genellikle ile kullanın:

-G --file-search-regex PATTERN Yalnızca adları PATTERN ile eşleşen dosyaları arayın.

ag -G "css$" important

ekran görüntüsü


1
ripgrep en algorythm hızlı silversearch daha iddia olduğunu ve ayrıca onurlandırıyor .gitignoredosya ve atlar .git, .svn, .hg.. klasörler.
ccpizza

@ccpizza Peki? Silver Searcher ayrıca .gitignoregizli ve ikili dosyaları varsayılan olarak onurlandırır ve yok sayar. Ayrıca daha fazla katkıda bulunanlar, Github'da daha fazla yıldız var (14700 vs 8300) ve şimdiden belediye başkanı dağıtımlarının depolarında. Lütfen güncellenmiş güvenilir bir üçüncü taraf kaynak karşılaştırması sağlayın. Bununla birlikte, ripgrepharika bir yazılım parçası görünüyor.
Pablo A

bunu bildiğim iyi oldu! Ben ripgrephiçbir şekilde yazar (lar) ile bağlı değilim , sadece benim gereksinimi uygun böylece diğer seçenekleri aramayı durdurdu.
ccpizza

Gümüş arayıcı da saygı duyuyor .gitignore. Dedi ki, rgkesinlikle şaşırtıcı. Öncelikle, unicode desteği var. Deneyimime göre (YMMV) rgsürekli olarak en az iki kat daha hızlı ag, sanırım Rust'ın regex ayrıştırıcısı, sanırım yıllar içinde henüz hazır agdeğildi yeni. rgdeterministik çıktı verebilir (ancak varsayılan olarak vermez), agsadece beyaz listeye girebilen dosya türlerini kara listeye alabilir, dosyaları boyuta göre (güle güle günlükleri) göz ardı edebilir. Hala yapamayacağım agçok satırlı eşleşmeye ihtiyacım olması durumunda kullanıyorum rg.
Pellmeister

2

Buluntu değişimi için fd . Orijinal find komutundan daha basit / daha sezgisel bir arayüze sahiptir ve biraz daha hızlıdır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.