Eu tenho um arquivo grande contendo uma string em cada linha. Eu gostaria de poder determinar rapidamente se uma string está no arquivo. Idealmente, isso seria feito usando um algoritmo binário do tipo chop.
Alguns pesquisadores do Google revelaram o look
comando com a -b
bandeira que promete localizar e gerar todas as strings que começam com um determinado prefixo usando um algoritmo de pesquisa binária. Infelizmente, ele não parece funcionar corretamente e retorna resultados nulos para as seqüências que eu sei que estão no arquivo (elas são retornadas corretamente pela grep
pesquisa equivalente ).
Alguém conhece outro utilitário ou estratégia para pesquisar esse arquivo com eficiência?
look
comando funcione corretamente, porque o look parece ignorar o código do idioma e apenas usa C como a classificação codificada, também abri um bug por causa deste comportamento confuso: bugzilla.kernel.org/show_bug.cgi?id=198011look -b
falhou para mim com um erroFile too large
. Eu acho que está tentando ler a coisa toda na memória.Respostas:
Há uma diferença essencial entre
grep
elook
:Salvo indicação explícita em contrário,
grep
ele encontrará padrões mesmo em algum lugar dentro das linhas. Paralook
os estados da página de manual:Não estou usando com
look
muita frequência, mas funcionou bem em um exemplo trivial que acabei de tentar.fonte
egrep "^TEST" sortedlist.txt | wc -l
obtiver 41.289 resultados. No entanto, oslook
comandos equivalenteslook -b TEST sortedlist.txt | wc -l
produzem apenas resultados de 1995. Eu quase me pergunto se há algum errolook
.look
esteja usando configurações de agrupamento diferentes do programa usado para classificar o arquivo.Talvez uma resposta um pouco tarde:
Sgrep irá ajudá-lo.
O Sgrep (grep classificado) procura nos arquivos de entrada classificados as linhas que correspondem a uma chave de pesquisa e gera as linhas correspondentes. Ao pesquisar arquivos grandes, o sgrep é muito mais rápido que o grep tradicional do Unix, mas com restrições significativas.
Você pode fazer o download da fonte aqui: https://sourceforge.net/projects/sgrep/?source=typ_redirect
e os documentos aqui: http://sgrep.sourceforge.net/
Outra maneira:
Não sei qual é o tamanho do arquivo.Talvez você deva tentar em paralelo:
/programming/9066609/fastest-possible-grep
Eu sempre faço grep com arquivos com tamanho> 100 GB, funciona bem.
fonte
sudo apt-get install sgrep
para obter o sgrep, o sgrep nos repositórios do buntu não é realmente esse sgrep, não tenho certeza se é a mesma coisa.Você pode fazer o hash do arquivo em pedaços e depois fazer o grep exatamente o que você deseja:
a pesquisa ficaria assim:
Isso faz duas coisas:
fonte
O sgrep pode funcionar para você:
A página do projeto http://sgrep.sourceforge.net/ diz:
Para inserção, no entanto, acho que não há solução melhor do que usar um banco de dados: /programming/10658380/shell-one-liner-to-add-a-line-to-a-sorted-file/ 33859372 # 33859372
fonte
sgrep
nos repositórios do Ubuntu é na verdade esse sgrep , que é projetado para "procurar um arquivo em busca de um padrão estruturado" e não tem nada a ver com a pesquisa binária.Se você quiser muito rápido (O (1) rápido), poderá criar um conjunto de hash para analisar. Não consegui encontrar uma implementação que me permitisse armazenar um conjunto de hash pré-criado em um arquivo e sondá-lo sem ter que ler o arquivo inteiro na memória, então rolei o meu .
Crie o conjunto de hash (
-b
/--build
):Teste o conjunto de hash (
-p
/--probe
):… Ou com uma string para procurar na entrada padrão:
Você pode silenciar a saída
--probe
com a opção-q
/--quiet
se estiver interessado apenas no status de saída:Para mais opções, consulte a descrição de uso acessível por meio da opção
-h
/--help
ou doREADME
arquivo que o acompanha .fonte