Alternative più veloci per "trovare" e "individuare"?


22

Mi piacerebbe usare "trova" e individuare "per cercare i file sorgente nel mio progetto, ma richiedono molto tempo per l'esecuzione. Esistono alternative più veloci a questi programmi che non conosco, o modi per accelerare le prestazioni di questi programmi?


2
locatedovrebbe già essere molto veloce, considerando che utilizza un indice predefinito (il principale avvertimento è che deve essere tenuto aggiornato), mentre finddeve leggere gli elenchi delle directory.
Afrazier,

2
Quale localizzazione stai usando? mlocate è molto più veloce di slocate da molto tempo (nota che qualunque pacchetto tu abbia installato, il comando è ancora localizzato, quindi controlla il gestore dei pacchetti)
Paul

@benhsu, quando corro find /usr/src -name fprintf.csul mio computer desktop OpenBSD, restituisce le posizioni di quei file sorgente in meno di 10 secondi. locate fprintf.c | grep '^/usr/src.*/fprintf.c$'torna in meno di un secondo. Qual è la tua definizione di "tempo di esecuzione" e come lo usi finde locate?
Kusalananda,

@Paul, sto usando mlocate.
benhsu,

@KAK, vorrei usare l'output di find / Locate per aprire un file in emacs. il caso d'uso che ho in mente è, desidero modificare il file, digito il nome del file (o qualche regexp corrispondente al nome del file) in emacs ed emacs utilizzerà find / Locate per visualizzare un elenco di file corrispondenti, quindi mi piacerà il tempo di risposta abbastanza veloce per essere interattivo (meno di 1 secondo). Ho circa 3 milioni di file in $ HOME, una cosa che posso fare è fare in modo che il mio comando find elimini alcuni dei file.
benhsu,

Risposte:


16

Ricerca di file sorgente in un progetto

Utilizzare un comando più semplice

Generalmente, è probabile che la fonte di un progetto si trovi in ​​un posto, forse in alcune sottodirectory nidificate non più di due o tre di profondità, quindi puoi usare un comando (possibilmente) più veloce come

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

Utilizzare i metadati del progetto

In un progetto C in genere avresti un Makefile. In altri progetti potresti avere qualcosa di simile. Questi possono essere un modo rapido per estrarre un elenco di file (e le loro posizioni) scrivere uno script che utilizza queste informazioni per individuare i file. Ho uno script "fonti" in modo da poter scrivere comandi come grep variable $(sources programname).

Accelerare la ricerca

Cerca meno posti, invece di find / …usarli find /path/to/project …dove possibile. Semplifica il più possibile i criteri di selezione. Utilizzare le pipeline per rinviare alcuni criteri di selezione se ciò è più efficiente.

Inoltre, puoi limitare la profondità della ricerca. Per me, questo migliora molto la velocità di "ricerca". È possibile utilizzare l'opzione -maxdepth. Ad esempio '-maxdepth 5'

Accelerare individuare

Assicurati che stia indicizzando le posizioni che ti interessano. Leggi la pagina man e fai uso di tutte le opzioni appropriate alla tua attività.

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

Rimuovi la necessità di cercare

Forse stai cercando perché hai dimenticato dove si trova o non è stato detto qualcosa. Nel primo caso, scrivere note (documentazione), nel secondo, chiedere? Convenzioni, standard e coerenza possono aiutare molto.


10

Ho usato la parte "speeding individuare" della risposta di RedGrittyBrick. Ho creato un db più piccolo:

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

poi lo indicò locate:locate -d /home/benhsu/ben.db


6

Una tattica che uso è quella di applicare l' -maxdepthopzione con find:

find -maxdepth 1 -iname "*target*"

Ripeti con profondità crescenti fino a trovare quello che cerchi o non ti stanchi di guardare. È probabile che le prime iterazioni ritornino istantaneamente.

Questo ti assicura di non perdere tempo in anticipo a guardare le profondità di enormi sotto-alberi quando è più probabile che ciò che stai cercando sia vicino alla base della gerarchia.


Ecco uno script di esempio per automatizzare questo processo (Ctrl-C quando vedi quello che vuoi):

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

Si noti che la ridondanza intrinseca coinvolta (ogni passaggio dovrà attraversare le cartelle elaborate nei passaggi precedenti) sarà ampiamente ottimizzata tramite la memorizzazione nella cache del disco.

Perché findquesto ordine di ricerca non è integrato? Forse perché sarebbe complicato / impossibile implementarlo se si presupponesse inaccettabile l'attraversamento ridondante. L'esistenza -depthdell'opzione suggerisce la possibilità, ma purtroppo ...


1
... eseguendo così una ricerca "ampia prima".
nobar

3

Un'altra soluzione semplice è utilizzare il più recente globbing a guscio esteso. Abilitare:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: già abilitato

Quindi, puoi eseguire comandi come questo nella directory di origine di livello superiore:

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

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

Questo ha il vantaggio di cercare ricorsivamente in tutte le sottodirectory ed è molto veloce.


3

Il cercatore d'argento

Potresti trovare utile la ricerca molto rapida del contenuto di un numero enorme di file di codice sorgente. Basta digitare ag <keyword>. Ecco alcuni dei miei risultati apt show silversearcher-ag:

Di solito lo uso con:

-G --file-search-regex PATTERN Cerca solo i file i cui nomi corrispondono a PATTERN.

ag -G "css$" important

immagine dello schermo


1
la del ripgrep algoritmo è presumibilmente più veloce di silversearch, e onora anche .gitignorefile e salta .git, .svn, .hg.. cartelle.
ccpizza,

@ccpizza Quindi? Silver Searcher onora .gitignoree ignora anche i file nascosti e binari per impostazione predefinita. Hanno anche più collaboratori, più stelle su Github (14700 contro 8300) ed è già in procinto di distribuire sindaci. Fornisci un confronto di fonti di terze parti affidabile aggiornato. Tuttavia, ripgrepsembra un ottimo software.
Pablo A

buono a sapersi! non sono affiliato con gli autori ripgrepin alcun modo, si adatta solo alle mie esigenze, quindi ho smesso di cercare altre opzioni.
ccpizza,

Anche il cercatore d'argento rispetta .gitignore. Detto questo, rgè assolutamente sorprendente. Prima di tutto, ha il supporto Unicode. Nella mia esperienzarg costantemente almeno due volte più veloce di ag(YMMV), suppongo sia dovuto al parser regex di Rust, che ovviamente non era pronto, ma negli anni agera nuovo. rgpuò dare un output deterministico (ma non di default), può inserire nella blacklist tipi di file dove agpuò solo inserire nella whitelist, può ignorare i file in base alla dimensione (ciao ciao registri). Uso ancora agnel caso avessi bisogno di una corrispondenza multilinea, cosa che rgnon posso fare.
The Pellmeister

2

Per una sostituzione di ricerca, controlla fd . Ha un'interfaccia più semplice / più intuitiva rispetto al comando di ricerca originale ed è un po 'più veloce.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.