The objective is to generate a kind of index for each keyword:
Em seguida, use o software de indexação em vez do grep. Tive muito sucesso ao usar pesquisa de códigos em todo o Arquivo CPAN .
Atualmente estou enfrentando um "problema de desempenho" ao usar o grep. Eu estou tentando localizar as ocorrências de muitas (mais de 10.000) palavras-chave em muitos arquivos (pense tamanho do repositório do kernel Linux). O objetivo é gerar um tipo de índice para cada palavra-chave:
keyword: my_keyword
filepath 1
filepath 2
------
keyword: my_keyword2
...
Sendo relativamente novo no shell de scripts, tentei algumas abordagens ingênuas:
while read LINE; do
echo "keyword: "$LINE >> $OUTPUT_FILE
grep -E -r --include='Makefile*' "($LINE)" . >> "$OUTPUT_FILE"
echo "-----"
done < $KEYWORD_FILE
Isso leva cerca de 45 minutos para ser concluído, com os resultados esperados.
Nota: todas as palavras-chave que eu procuro estão localizadas em um arquivo ("KEYWORD_FILE", portanto, corrigidas antes de iniciar qualquer coisa) e os arquivos nos quais pesquisar podem ser determinados antes que a pesquisa seja iniciada. Tentei armazenar a lista de arquivos para pesquisar antes da pesquisa assim:
file_set=( $(find . -name "Kbuild*" -o -name "Makefile*") )
e, em seguida, substitua a chamada grep por
echo {$file_set[*]} | parallel -k -j+0 -n 1000 -m grep -H -l -w "\($LINE\)" >> "$OUTPUT_FILE"
Demora cerca de uma hora para concluir…
Pergunta: considerando que eu posso usar qualquer técnica que eu queira, desde que seja compatível, como isso pode ser feito "mais rápido" e / ou mais eficiente?
Talvez grep
não seja a ferramenta a ser usada, e meu uso de parallel
está errado ... todas as ideias são bem-vindas!
The objective is to generate a kind of index for each keyword:
Em seguida, use o software de indexação em vez do grep. Tive muito sucesso ao usar pesquisa de códigos em todo o Arquivo CPAN .
Eu escreveria um script em Perl (sim, eu sei que o Python é atualmente muito mais favorecido ...) que faz slurps nas 10.000 palavras-chave, lê cada arquivo e para cada linha vê se algumas delas correspondem. Se houver uma correspondência, armazene-a sob a palavra-chave como arquivo / linha (um hash funciona bem aqui). Uma vez feito com o conjunto, passe o hash cuspindo as descobertas para cada palavra-chave.
Perl (e Python) é uma linguagem (semi) compilada, o script é compilado em uma representação interna (bastante compacta, fácil e rápida de interpretar), e essa forma interna recebe (alguns) "otimizadores" de amor. A velocidade não é a mesma do C, mas não deve ser 10 vezes mais lenta.
No final, o seu comentário acima acerta na cabeça: Seu tempo (escrever, depurar ou buscar, construir, aprender a usar) é muito mais valioso do que o tempo da máquina (se você deixá-lo funcionando durante a noite, quem se importa se for feito por dez horas ou seis horas ...).
Usar os switches -f e -F no grep provavelmente acelerará um pouco as coisas. O Grep pode ser bastante inteligente sobre como lidar com correspondências para múltiplos padrões.
The objective is to generate a kind of index for each keyword
Então, talvez a solução seja um mecanismo de pesquisa (por exemplo, mnogo)?
Estes pontos vêm à minha mente:
-l / --files-with-matches
, cobrindo inutilmente até o final de cada arquivo. Infelizmente não há (AFAIK) nenhuma combinação de --files-with-matches
com vários padrões (pelo menos não da maneira que você precisa). Isso pode ser feito no awk. O awk não pode ser chamado recursivamente (AFAIK), mas pode ser chamado através de uma localização com muitos arquivos. -printf .
é suficiente e grave a saída em / dev / null. Tags performance grep shell