osx bash grep - localizando termos de pesquisa em um arquivo grande com uma única linha

-1

Existe uma linha de comando unix simples que eu posso inserir, o que me permite isolar 512 bytes de cada lado de um termo de pesquisa, mesmo que haja apenas uma "linha" em um arquivo de texto muito grande?

Ok, isso deve ser fácil.

Últimas palavras famosas.

Não estou familiarizado com o grep, mas parece que ele é usado principalmente para filtrar linhas na entrada que contêm termos de pesquisa.

Eu tenho um arquivo json muito grande que eu baixei e quero pesquisar por um termo específico.

antes de clicar no link - é mais de 244MB, então esteja avisado - é de   a máquina de recuo da internet e contém listas de arquivos zip de fotos arquivadas. Eu estou tentando encontrar o meu.

A interface da web deles está quebrada, então eu encontrei o arquivo json que eles publicam aqui - é o último da lista.

quando busco meu nome de usuário, ele o encontra, mas continua a despejar a linha no console. o problema é que a linha tem 244 MB de comprimento e é a única linha no arquivo.

Eu tentei usar menos, mas não consegui fazer isso - é muito lento e parece ter o mesmo problema.

existe uma linha de comando unix simples que eu possa inserir, o que me permite isolar, digamos, 512 bytes de cada lado de um termo de pesquisa?

    
por unsynchronized 05.06.2014 / 01:50

3 respostas

1

sed é quase o que você precisa, assim:

sed 's/.*\(.\{100\}eubike.\{100\}\).*//' webshots-index-20121231-index.json

retorna isso para o console:

20121017032138","warc",30012950425],["eusbike","2012-11-11 09:41","20121111040120/webshots.com-user-eusbike-20121111-094102.warc.gz",34212598,"20121111040120","warc",19238806437],["EUSCALDUN","2012-11-17 13:

mas e é um grande MAS: você está limitado por RE_DUP_MAX para 255 de cada lado. Mesmo para os 100 lados mostrados, levou 16 minutos para processar no meu macbook pro. Apenas 2 minutos para 10 caracteres de cada lado. Eu não tenho tempo para testar quanto tempo levaria para 255 de cada lado, provavelmente em torno de 50 minutos. As razões para a limitação são mostradas em ftp://ftp.ics.uci.edu/pub/centos0/ics-custom-build/BUILD/nagios-plugins-1.4.13/gl/regex.h

Acho que você pode estar sem sorte se quiser muitos caracteres em cada lado do seu termo de pesquisa.

    
por 05.06.2014 / 07:40
2

Como você já tem o arquivo json baixado, você pode realizar algumas manipulações de arquivo para facilitar a pesquisa.

Eu fiz o download das primeiras centenas de bytes do arquivo json e vejo que o arquivo é assim:

["entry1","date1","file1.gz",int1,"string1","string1",int1],["entry2","date2","file2.gz",int2,"string2","string2",int2],[...

Parece que cada entrada está em uma matriz json separada, separada por ],[ . Você pode usar sed para substituir esses caracteres por uma quebra de linha.

sed 's_\],\[_\]\n\[_g' json_file > json_file_with_breaks

Este comando irá inserir uma quebra de linha após cada entrada, então você receberá uma entrada por linha:

[... entry1 ...],
[... entry2 ...],
...

A saída será salva em um novo arquivo, json_file_with_breaks . Eu recomendo isso, porque se você precisar fazer várias pesquisas, executar grep no novo arquivo será mais rápido do que executar sed a cada vez e a saída da tubulação para grep . NB : o novo arquivo também terá tamanho de 244 MB!

O próximo passo é usar grep para pesquisar o novo arquivo:

grep 'search term' json_file_with_breaks
    
por 05.06.2014 / 02:41
0

Isso está mais na linha da sua pergunta original

Is there simple unix command line I can enter which lets me isolate say 512 bytes either side of a search term?

Na página grep man:

-b, --byte-offset  
      Print the 0-based byte offset within the  input  file  before
      each  line  of output.  If -o (--only-matching) is specified,
      print the offset of the matching part itself.

Então, você pode pesquisar sua string assim:

grep -o -b 'my search term' json_file

Saída:

1234567:my search term
9876543:my search term
...

Cada linha contém o deslocamento de bytes do início do arquivo de cada ocorrência de "meu termo de pesquisa".

Você pode usar cut -bN-M para selecionar bytes do Nth ao Mth no arquivo:

cut -b$((1234567 - 512))-$((1234567 + 512)) json_file
cut -b$((9876543 - 512))-$((9876543 + 512)) json_file

Você pode automatizar o processo acima com um loop while :

grep -o -b 'my search term' json_file | cut -d: -f1 | while read pos; do cut -b$((pos - 512))-$((pos + 512)); done

Isso localiza todas as ocorrências de 'meu termo de pesquisa' no arquivo, corta suas posições da saída grep e, para cada posição, corta 512 bytes em ambos os lados da correspondência do arquivo json (por um total de 1024 bytes em torno da partida).

    
por 05.06.2014 / 03:12