Schnellere Alternativen zum "Finden" und "Finden"?

28476
benhsu

Ich möchte "find" und "locate" verwenden, um nach Quelldateien in meinem Projekt zu suchen, aber es dauert lange, bis sie ausgeführt werden. Gibt es schnellere Alternativen zu diesen Programmen, über die ich keine Ahnung habe, oder Möglichkeiten, die Leistung zu beschleunigen? dieser Programme?

15
"locate" sollte bereits sehr schnell sein, wenn man bedenkt, dass er einen vorgefertigten Index verwendet (der Hauptvorbehalt ist, dass er auf dem neuesten Stand gehalten werden muss), während "find" die Verzeichnislisten lesen muss. afrazier vor 13 Jahren 2
Welchen Ort benutzen Sie? mlocate ist bei weitem schneller als slocate (beachten Sie, dass der Befehl immer das lokalisierte Paket ist, prüfen Sie Ihren Paket-Manager.) Paul vor 13 Jahren 2
@benhsu, wenn ich `find / usr / src -name fprintf.c` auf meinem OpenBSD-Desktop-Computer ausführen, werden die Speicherorte dieser Quelldateien in weniger als 10 Sekunden zurückgegeben. `Finde fprintf.c | grep '^ / usr / src. * / fprintf.c $' `kommt wieder unter eine Sekunde. Was ist Ihre Definition von "long time to run" und wie verwenden Sie "find" und "locate"? Kusalananda vor 13 Jahren 0
@ Paul, ich benutze mlocate. benhsu vor 13 Jahren 0
@KAK, ich möchte die Ausgabe von find / locate verwenden, um eine Datei in emacs zu öffnen. Der Anwendungsfall, den ich mir vorstelle, ist, ich möchte die Datei bearbeiten, ich gebe den Dateinamen (oder einen mit dem Dateinamen übereinstimmenden regulären Ausdruck) in emacs ein, und emacs verwendet find / locate, um eine Liste der dazugehörigen Dateien anzuzeigen. Ich möchte die Reaktionszeit schnell genug, um interaktiv zu sein (unter 1 Sekunde). Ich habe ungefähr 3 Millionen Dateien in $ HOME, eine Sache, die ich tun kann, ist, meinen Befehl zum Entfernen einiger Dateien auszulöschen. benhsu vor 13 Jahren 0

5 Antworten auf die Frage

14
RedGrittyBrick

Suchen nach Quelldateien in einem Projekt

Verwenden Sie einen einfacheren Befehl

Im Allgemeinen befindet sich die Quelle für ein Projekt wahrscheinlich an einem Ort, möglicherweise in einigen verschachtelten Unterverzeichnissen, die nicht mehr als zwei oder drei tief sind. Daher können Sie einen (möglicherweise) schnelleren Befehl wie

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

Verwenden Sie Projektmetadaten

In einem C-Projekt haben Sie normalerweise ein Makefile. In anderen Projekten haben Sie möglicherweise etwas Ähnliches. Dies kann eine schnelle Methode zum Extrahieren einer Liste von Dateien (und ihrer Speicherorte) sein. Schreiben Sie ein Skript, das diese Informationen zum Auffinden von Dateien verwendet. Ich habe ein "sources" -Skript, damit ich Befehle schreiben kann grep variable $(sources programname).

Suche beschleunigen

Suchen weniger Orte, statt find / …Verwendung, find /path/to/project …wo möglich. Vereinfachen Sie die Auswahlkriterien so gut wie möglich. Verwenden Sie Pipelines, um einige Auswahlkriterien zu verschieben, wenn dies effizienter ist.

Sie können auch die Suchtiefe einschränken. Für mich verbessert dies die Geschwindigkeit des 'Findens' sehr. Sie können den Schalter -maxdepth verwenden. Zum Beispiel '-maxdepth 5'

Lokalisieren beschleunigen

Stellen Sie sicher, dass die Standorte indiziert werden, an denen Sie interessiert sind. Lesen Sie die Manpage und nutzen Sie die Optionen, die für Ihre Aufgabe geeignet sind.

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

Beseitigen Sie die Notwendigkeit der Suche

Vielleicht suchen Sie, weil Sie vergessen haben, wo etwas ist oder was Ihnen nicht gesagt wurde. Im ersten Fall Notizen schreiben (Dokumentation), im letzteren fragen? Konventionen, Standards und Konsistenz können sehr helfen.

8
benhsu

Ich habe den "beschleunigten Ortungs-Teil" von RedGrittyBricks Antwort verwendet. Ich habe eine kleinere Datenbank erstellt:

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

dann zeigte locatees darauf:locate -d /home/benhsu/ben.db

4
nobar

Eine Taktik, die ich benutze, ist die Anwendung der -maxdepthOption mit find:

find -maxdepth 1 -iname "*target*" 

Wiederholen Sie den Vorgang mit zunehmender Tiefe, bis Sie das Gesuchte gefunden haben oder das Suchen müde wird. Die ersten paar Iterationen werden wahrscheinlich sofort zurückkehren.

Dadurch wird sichergestellt, dass Sie keine Zeit vergeuden, indem Sie durch die Tiefen massiver Unterbäume blicken, wenn das, was Sie suchen, eher in der Nähe der Hierarchie liegt.


Hier ein Beispielskript zum Automatisieren dieses Prozesses (Strg-C, wenn Sie sehen, was Sie möchten):

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

Beachten Sie, dass die inhärente Redundanz (bei jedem Durchlauf die Ordner, die in vorherigen Durchläufen verarbeitet wurden, durchlaufen werden muss) weitgehend durch das Zwischenspeichern von Festplatten optimiert wird.

Warum gibt findes diese Suchreihenfolge nicht als integrierte Funktion? Vielleicht, weil es kompliziert / unmöglich zu implementieren wäre, wenn Sie davon ausgehen, dass das redundante Traversieren nicht akzeptabel ist. Die Existenz der -depthOption weist auf die Möglichkeit hin, aber leider ...

... und führt so eine "Breitensuche" durch. nobar vor 8 Jahren 1
1
dannyw

Eine andere einfache Lösung ist die Verwendung eines neueren erweiterten Shell-Globings. Ermöglichen:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: bereits aktiviert

Dann können Sie Befehle wie diese im Quellverzeichnis der obersten Ebene ausführen:

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

Dies hat den Vorteil, dass es alle Unterverzeichnisse rekursiv durchsucht und sehr schnell ist.

0
Pablo Bianchi

Der silberne Bogenschütze

Es könnte hilfreich sein, den Inhalt einer großen Anzahl von Quellcodedateien sehr schnell zu durchsuchen . Einfach tippen ag <keyword>. Hier einige meiner Ausgaben apt show silversearcher-ag:

  • Paket : silversearcher-ag
  • Betreuer : Hajime Mizuno
  • Homepage : https://github.com/ggreer/the_silver_searcher
  • Beschreibung : Sehr schnelles grep-ähnliches Programm, Alternative zu ack-grep Der Silver Searcher ist ein grep-ähnliches Programm, das von C implementiert wurde. Ein Versuch, etwas besseres als ack-grep zu machen. Es sucht etwa 3–5x schneller als ack-grep. Es ignoriert Dateimuster von .gitignore und .hgignore.

Bildschirmfoto

Die [ripgrep's] (https://github.com/BurntSushi/ripgrep) -Algorythm ist angeblich schneller als Silversearch und ehrt auch `.gitignore`-Dateien und überspringt` .git`, `.svn`,` .hg`. Ordner. ccpizza vor 6 Jahren 1
@ccpizza So? [The Silver Searcher] (https://github.com/ggreer/the_silver_searcher) berücksichtigt auch `.gitignore` und ignoriert standardmäßig ausgeblendete und binäre Dateien. Habe auch mehr Mitwirkende, mehr Stars auf Github (14700 vs. 8300) und ist bereits auf Repos von Mayor Distros. Bitte geben Sie einen aktualisierten zuverlässigen Quellenvergleich von Drittanbietern an. Trotzdem sieht "ripgrep" eine großartige Software aus. Pablo Bianchi vor 6 Jahren 0
gut zu wissen! Ich bin in keiner Weise mit Autor / en von "ripgrep" verbunden, es passte einfach zu meiner Anforderung, also hörte ich auf, nach anderen Optionen zu suchen. ccpizza vor 6 Jahren 0