Algo mais rápido que o grep? [fechadas]

1

Eu estou procurando uma ferramenta que seja mais rápida que o grep, talvez um multi-threaded grep, ou algo similar ... Eu tenho procurado por um monte de indexadores, mas eu não estou vendendo que eu preciso de um índice. ..

Eu tenho cerca de 100 milhões de arquivos de texto, que eu preciso para grep para correspondências de seqüência de caracteres exatas, ao encontrar uma correspondência de seqüência de caracteres, eu preciso do nome do arquivo onde a correspondência foi encontrada.

ie: grep -r 'exact match' > filepaths.log

São cerca de 4 TB de dados, e eu iniciei minha primeira pesquisa 6 dias atrás, e o grep ainda está em execução. Eu tenho outra dúzia de buscas para ir e eu não posso esperar 2 meses para recuperar todos esses nomes de arquivo =]

Eu revi o seguinte, no entanto, eu não acho que eu preciso de todos os sinos e assobios que esses indexadores vêm, eu só preciso do nome do arquivo onde o jogo ocorreu ...

  • dtSearch
  • Terrier
  • Lucene
  • Xapian
  • Recuo
  • Esfinge

e depois de passar horas lendo sobre todos esses motores, minha cabeça está girando, e eu gostaria de ter um multi-threaded grep lol, quaisquer idéias e / ou sugestões são muito apreciadas!

PS: Estou rodando o CentOS 6.5

EDIT: A pesquisa por multi-threaded grep retorna vários itens. Minha pergunta é, é um multi-threaded grep a melhor opção para o que estou fazendo?

EDIT2: Depois de alguns ajustes, é isso que eu tenho, e está indo muito mais rápido que o grep normal, eu ainda queria que fosse mais rápido ... Estou vendo meu disco esperar, e não é construindo ainda, eu posso fazer mais alguns ajustes, e def ainda interessado em qualquer sugestão =]

find . -type f -print0 | xargs -0 -n10 -P4 grep -m 1 -H -l 'search string'
    
por Jeffrey L. Roberts 20.12.2014 / 11:27

2 respostas

9

grep é de E / S, o que significa que sua velocidade é dominada pela velocidade com que consegue ler os arquivos que está pesquisando. Múltiplas pesquisas em paralelo podem competir umas com as outras pela E / S do disco, então você pode não ver muita aceleração.

Se você precisar apenas de nomes de arquivos correspondentes e não das correspondências encontradas nos arquivos, você deverá executar grep com o -l flag. Esse sinalizador faz com que o grep apenas imprima nomes de arquivos correspondentes e não imprima as linhas correspondentes. O valor aqui é que ele permite que o grep pare de pesquisar um arquivo depois de encontrar uma correspondência, para que possa reduzir a quantidade de trabalho que o grep precisa fazer.

Se você estiver pesquisando strings fixas em vez de expressões regulares, tente usar fgrep em vez de grep . O Fgrep é uma variante do grep que procura por strings fixas, e procurar por strings fixas é mais rápido do que executar uma pesquisa de expressões regulares. Você pode ou não ver qualquer melhoria disso, porque as versões modernas do grep são provavelmente inteligentes o suficiente para otimizar pesquisas de cadeias fixas de qualquer maneira.

Se você quiser tentar executar várias pesquisas em paralelo, poderá fazê-lo usando utilitários de shell. Uma maneira seria criar uma lista de nomes de arquivos, dividi-la em partes e executar o grep separadamente para cada lista:

find /path/to/files -type f -print | split -l 10000000 list.
for file in list.*; do
    grep -f ${file} -l 'some text' > ${file}.out &
done
wait
cat $*.out > filepaths.log
rm list.*

Isso usa find para localizar os arquivos, divide a lista de nomes de arquivos em grupos de dez milhões e executa grep em paralelo para cada grupo. A saída dos greps está reunida no final. Isso deve funcionar para arquivos com nomes típicos, mas falharia em arquivos que tinham novas linhas em seus nomes, por exemplo.

Outra abordagem usa xargs. Primeiro, você teria que escrever um script de shell simples que executa grep em segundo plano:

#!/bin/bash
grep -l 'search text' "$@" >> grep.$$.out &

Isso executará o grep na lista de arquivos especificados como argumentos para o script, gravando o resultado em um arquivo com o nome do PID do processo. O processo grep é executado em segundo plano.

Então você executaria o script assim:

find /path/to/files -type f -print0 | xargs -0 -r /my/grep/script
[ wait for those to finish ]
cat grep.*.out > filepaths.log
rm grep.*.out

Nesse caso, xargs agrupará os nomes de arquivos em grupos e executará o script uma vez para cada grupo. O script executará uma instância do grep uma vez para cada grupo. Depois que todas as instâncias do grep terminarem, você poderá combinar suas saídas. Infelizmente, não consegui pensar em uma maneira inteligente de esperar automaticamente que as instâncias do grep terminem aqui, então talvez seja necessário fazer isso manualmente.

    
por 20.12.2014 / 16:45
0

Parece que você precisa de um script ou programa pequeno que execute várias instâncias (ou seja, 8 x grep poderiam ser executados em paralelo em um i7 moderno com 4 núcleos / 8threads) do grep e concatenar ou mesclar a saída, mais do que você precisa um grep mais rápido.

Como fazer esse script é uma outra pergunta, mas é assim que eu atacaria o seu problema.

    
por 20.12.2014 / 11:51