Alternativas mais rápidas para “encontrar” e “localizar”?

22

Eu gostaria de usar "encontrar" e localizar "para procurar arquivos de origem no meu projeto, mas eles demoram muito tempo para serem executados. Existem alternativas mais rápidas para esses programas que eu não conheço ou maneiras de acelerar o desempenho desses programas?

benhsu
fonte
2
locatejá deve ser bastante rápido, considerando que ele usa um índice pré-criado (a principal ressalva é que ele precisa ser atualizado), enquanto findprecisa ler as listagens de diretório.
afrazier 29/09/11
2
Qual local você está usando? mlocate é mais rápido que slocate por um longo caminho (note que qualquer pacote que você tem instalado, o comando ainda é localizar, de modo a verificar o seu gerenciador de pacotes)
Paul
@benhsu, quando eu corro find /usr/src -name fprintf.cna minha máquina desktop OpenBSD, ele retorna os locais desses arquivos fonte em menos de 10 segundos. locate fprintf.c | grep '^/usr/src.*/fprintf.c$'volta em menos de um segundo. Qual é a sua definição de "muito tempo para executar" e como você usa finde locate?
Kusalananda 29/09
@Paul, estou usando mlocate.
benhsu 29/09/11
@KAK, eu gostaria de usar a saída do find / find para abrir um arquivo no emacs. o caso de uso que tenho em mente é: desejo editar o arquivo, digitar o nome do arquivo (ou alguma regexp que corresponda ao nome do arquivo) no emacs, e o emacs usará localizar / localizar para exibir uma lista de arquivos correspondentes, então, gostarei do tempo de resposta rápido o suficiente para ser interativo (menos de 1 segundo). Eu tenho cerca de 3 milhões de arquivos no $ HOME, uma coisa que posso fazer é fazer com que meu comando find apague alguns dos arquivos.
precisa saber é o seguinte

Respostas:

16

Procurando por arquivos de origem em um projeto

Use um comando mais simples

Geralmente, é provável que a origem de um projeto esteja em um local, talvez em alguns subdiretórios aninhados com mais de dois ou três de profundidade, para que você possa usar um comando (possivelmente) mais rápido, como

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

Fazer uso dos metadados do projeto

Em um projeto C, você normalmente teria um Makefile. Em outros projetos, você pode ter algo semelhante. Essa pode ser uma maneira rápida de extrair uma lista de arquivos (e seus locais). Escrever um script que utilize essas informações para localizar arquivos. Eu tenho um script "sources" para que eu possa escrever comandos como grep variable $(sources programname).

Acelerando a localização

Pesquise menos lugares, em vez de find / …usar sempre find /path/to/project …que possível. Simplifique os critérios de seleção o máximo possível. Use pipelines para adiar alguns critérios de seleção, se isso for mais eficiente.

Além disso, você pode limitar a profundidade da pesquisa. Para mim, isso melhora muito a velocidade de 'encontrar'. Você pode usar a opção -maxdepth. Por exemplo '-maxdepth 5'

Acelerando a localização

Verifique se está indexando os locais nos quais você está interessado. Leia a página de manual e use as opções apropriadas para sua tarefa.

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

Remova a necessidade de pesquisar

Talvez você esteja pesquisando porque esqueceu onde algo é ou não foi dito. No primeiro caso, escreva notas (documentação), no último, pergunte? Convenções, padrões e consistência podem ajudar muito.

RedGrittyBrick
fonte
10

Eu usei a parte "acelerando a localização" da resposta do RedGrittyBrick. Eu criei um db menor:

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

então apontou locatepara ele:locate -d /home/benhsu/ben.db

benhsu
fonte
6

Uma tática que eu uso é aplicar a -maxdepthopção com find:

find -maxdepth 1 -iname "*target*"

Repita com profundidades crescentes até encontrar o que está procurando ou se cansar de procurar. As primeiras iterações provavelmente retornarão instantaneamente.

Isso garante que você não perca tempo olhando as profundezas de subárvores maciças quando o que você está procurando tem maior probabilidade de estar perto da base da hierarquia.


Aqui está um exemplo de script para automatizar esse processo (Ctrl-C quando você vir o que deseja):

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

Observe que a redundância inerente envolvida (cada passagem terá que percorrer as pastas processadas nas passagens anteriores) será amplamente otimizada através do cache de disco.

Por que findessa ordem de pesquisa não possui um recurso interno? Talvez porque seria complicado / impossível de implementar se você assumisse que a travessia redundante era inaceitável. A existência da -depthopção sugere a possibilidade, mas infelizmente ...

nobar
fonte
11
... realizando uma pesquisa "em primeiro lugar".
dec
3

Outra solução fácil é usar globbing de shell estendido mais recente. Para habilitar:

  • bash: shopt -s globstar
  • ksh: set -o globstar
  • zsh: já ativado

Em seguida, você pode executar comandos como este no diretório de origem de nível superior:

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

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

Isso tem a vantagem de pesquisar recursivamente em todos os subdiretórios e é muito rápido.

dannyw
fonte
3

O pesquisador de prata

Você pode achar útil pesquisar muito rapidamente o conteúdo de um grande número de arquivos de código-fonte. Apenas digite ag <keyword>. Aqui estão alguns dos resultados do meu apt show silversearcher-ag:

Eu costumo usá-lo com:

-G --file-search-regex PATTERN Pesquise apenas arquivos cujos nomes correspondam a PATTERN.

ag -G "css$" important

captura de tela

Pablo A
fonte
11
o de ripgrep algorythm é supostamente mais rápido do que silversearch, e também homenageia .gitignorearquivos e saltos .git, .svn, .hg.. pastas.
Ccpizza
@ccpizza Então? O Silver Searcher também honra .gitignoree ignora arquivos ocultos e binários por padrão. Também tem mais colaboradores, mais estrelas no Github (14700 vs 8300) e já está em repositórios de distribuição de prefeitos. Forneça uma comparação confiável e atualizada de fontes de terceiros. No entanto, ripgrepparece um ótimo software.
Pablo A
bom saber! eu não sou afiliado ao (s) autor (es) de ripgrepqualquer forma, ele se encaixa no meu requisito, então parei de procurar outras opções.
Ccpizza
O pesquisador de prata .gitignoretambém respeita . Dito isto, rgé absolutamente incrível. Primeiro, ele possui suporte unicode. Na minha experiência, rgpelo menos duas vezes mais rápido que ag(YMMV), acho que é devido ao analisador de expressões regulares de Rust, que obviamente ainda não estava pronto nos anos anteriores ag. rgpode fornecer uma saída determinística (mas não aparece por padrão), pode colocar na lista negra os tipos de arquivo, onde agsó pode colocar na lista de permissões, pode ignorar arquivos com base no tamanho (registros de adeus). Ainda uso agno caso de precisar de correspondência multilinha, o que rgnão pode ser feito.
The Pellmeister
2

Para uma substituição de localização, consulte fd . Ele possui uma interface mais simples / intuitiva do que o comando find original e é um pouco mais rápido.

Keith Hughitt
fonte