¿Alternativas más rápidas para "encontrar" y "localizar"?

22

Me gustaría usar "buscar" y localizar "para buscar archivos fuente en mi proyecto, pero tardan mucho en ejecutarse. ¿Hay alternativas más rápidas a estos programas que no conozco, o formas de acelerar el rendimiento? de estos programas?

benhsu
fuente
2
locateya debería ser bastante rápido, teniendo en cuenta que usa un índice preconstruido (la advertencia principal es que debe mantenerse actualizado), mientras que findtiene que leer los listados del directorio.
Afrazier
2
¿Qué ubicación estás usando? mlocate es mucho más rápido que la pendiente por un largo camino (tenga en cuenta que, sea cual sea el paquete que haya instalado, el comando aún se encuentra, así que verifique su administrador de paquetes)
Paul
@benhsu, cuando ejecuto find /usr/src -name fprintf.cen mi máquina de escritorio OpenBSD, devuelve las ubicaciones de esos archivos de origen en menos de 10 segundos. locate fprintf.c | grep '^/usr/src.*/fprintf.c$'vuelve en menos de un segundo. ¿Cuál es su definición de "mucho tiempo para correr" y cómo usa findy locate?
Kusalananda
@Paul, estoy usando mlocate.
benhsu
@KAK, me gustaría usar la salida de buscar / localizar para abrir un archivo en emacs. El caso de uso que tengo en mente es, deseo editar el archivo, escribo el nombre del archivo (o alguna expresión regular que coincida con el nombre del archivo) en emacs, y emacs usará buscar / localizar para que aparezca una lista de archivos que coincidan, así que me gustará el tiempo de respuesta lo suficientemente rápido como para ser interactivo (menos de 1 segundo). Tengo alrededor de 3 millones de archivos en $ HOME, una cosa que puedo hacer es hacer que mi comando find elimine algunos de los archivos.
benhsu

Respuestas:

16

Buscando archivos fuente en un proyecto

Use un comando más simple

En general, es probable que la fuente de un proyecto esté en un lugar, tal vez en algunos subdirectorios anidados no más de dos o tres de profundidad, por lo que puede usar un comando (posiblemente) más rápido como

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

Hacer uso de los metadatos del proyecto.

En un proyecto de C que habitualmente se tiene un Makefile. En otros proyectos, puede tener algo similar. Estos pueden ser una manera rápida para extraer una lista de archivos (y sus ubicaciones) escribir un script que hace uso de esta información para localizar archivos. Tengo un script "fuentes", por lo que puedo escribir comandos como grep variable $(sources programname).

Acelerando encontrar

Busque en menos lugares, en lugar de find / …usar find /path/to/project …donde sea posible. Simplifique los criterios de selección tanto como sea posible. Use tuberías para diferir algunos criterios de selección si eso es más eficiente.

Además, puede limitar la profundidad de búsqueda. Para mí, esto mejora mucho la velocidad de 'encontrar'. Puede usar el modificador -maxdepth. Por ejemplo '-maxdepth 5'

Acelerando localizar

Asegúrese de que está indexando las ubicaciones que le interesan. Lea la página de manual y utilice las opciones que sean apropiadas para su tarea.

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

Elimina la necesidad de buscar

Tal vez estás buscando porque has olvidado dónde se dice o no se dice algo. En el primer caso, escriba notas (documentación), en el segundo, pregunte? Las convenciones, los estándares y la coherencia pueden ayudar mucho.

RedGrittyBrick
fuente
10

Usé la parte de "acelerar la localización" de la respuesta de RedGrittyBrick. Creé un db más pequeño:

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

luego lo señaló locate:locate -d /home/benhsu/ben.db

benhsu
fuente
6

Una táctica que uso es aplicar la -maxdepthopción con find:

find -maxdepth 1 -iname "*target*"

Repita con profundidades crecientes hasta que encuentre lo que está buscando o se canse de buscar. Es probable que las primeras iteraciones vuelvan instantáneamente.

Esto garantiza que no pierdas el tiempo inicial mirando a través de las profundidades de los subárboles masivos cuando lo que estás buscando es más probable que esté cerca de la base de la jerarquía.


Aquí hay un script de ejemplo para automatizar este proceso (Ctrl-C cuando ve lo que quiere):

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

Tenga en cuenta que la redundancia inherente involucrada (cada pasada tendrá que atravesar las carpetas procesadas en pasadas anteriores) se optimizará en gran medida a través del almacenamiento en caché de disco.

¿Por qué no findtiene este orden de búsqueda como una función incorporada? Tal vez porque sería complicado / imposible de implementar si asumiera que el recorrido redundante es inaceptable. La existencia de la -depthopción sugiere la posibilidad, pero desgraciadamente ...

sin bar
fuente
1
... realizando así una búsqueda de "amplitud primero".
nobar
3

Otra solución fácil es usar un globing de shell extendido más nuevo. Para permitir:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: ya habilitado

Luego, puede ejecutar comandos como este en el directorio fuente de nivel superior:

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

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

Esto tiene la ventaja de que busca de forma recursiva en todos los subdirectorios y es muy rápido.

dannyw
fuente
3

El buscador de plata

Puede resultarle útil para buscar muy rápidamente el contenido de una gran cantidad de archivos de código fuente. Solo escribe ag <keyword>. Aquí algunos de los resultados de mi apt show silversearcher-ag:

Usualmente lo uso con:

-G --file-search-regex PATTERN Solo busque archivos cuyos nombres coincidan con PATTERN.

ag -G "css$" important

captura de pantalla

Pablo A
fuente
1
la de ripgrep algoritmo es supuestamente más rápido que silversearch, y también rinde homenaje a .gitignorelos archivos y saltos .git, .svn, .hg.. carpetas.
ccpizza
@ccpizza Entonces? Silver Searcher también honra .gitignoree ignora los archivos ocultos y binarios de forma predeterminada. También tienen más contribuyentes, más estrellas en Github (14700 vs 8300) y ya está en repos de las principales distribuciones. Proporcione una comparación actualizada de fuentes confiables de terceros. Sin embargo, ripgrepparece una gran pieza de software.
Pablo A
¡bueno saber! No estoy afiliado a los autores de ripgrepninguna manera, solo se ajusta a mis requisitos, así que dejé de buscar otras opciones.
ccpizza
El buscador de plata .gitignoretambién respeta . Dicho eso, rges absolutamente asombroso. En primer lugar, tiene soporte Unicode. En mi experiencia, rgal menos dos veces más rápido que ag(YMMV), supongo que se debe al analizador de expresiones regulares de Rust, que obviamente todavía no estaba listo en los años agnuevos. rgpuede proporcionar resultados deterministas (pero no lo hace de manera predeterminada), puede incluir en la lista negra los tipos de archivos donde agsolo puede incluir en la lista blanca, puede ignorar los archivos según el tamaño (registros de bye bye). Todavía lo uso agen caso de que necesite coincidencia multilínea, lo que rgno puede hacer.
The Pellmeister
2

Para encontrar un reemplazo, consulte fd . Tiene una interfaz más simple / más intuitiva que el comando de búsqueda original, y es bastante más rápido.

Keith Hughitt
fuente