Como começar a processar um arquivo em um deslocamento?

2

Caso de uso: você tem um arquivo de log de vários GB durante uma semana inteira e precisa pesquisar algo que aconteceu no sábado usando, por exemplo, grep . Fazendo uma suposição instruída, você assume que iniciar a pesquisa a partir do meio do arquivo reduzirá em mais de metade o tempo de processamento (já que definitivamente não terá que processar todo o resto do arquivo), sem pular nenhum dado relevante. Isso é possível?

    
por l0b0 09.10.2013 / 10:36

4 respostas

4

Supondo que seus dados estão em ordem cronológica:

  1. Obtenha o tamanho do arquivo procurando no final e fazendo ftell() ;
  2. Divida esse resultado por 2;
  3. Use fseek() para procurar esse local;
  4. Procure o início da próxima linha chamando getline() once;
  5. Use strptime() para descobrir em que data você está no momento;
  6. Faça uma pesquisa binária, repetindo as etapas 4 e 5 até encontrar a linha desejada.
por 09.10.2013 / 10:47
2

Você pode usar dd ao longo das linhas de:

dd if=log skip=xK bs=1M

que ignoraria x * 1024 blocos de tamanho 1M (2 ^ 20). Veja dd(1) para detalhes sobre o manuseio de unidades.

Se você quiser automatizar a pesquisa binária, supondo que seu log tenha a forma usual <date> [data] , você pode canalizar a saída para head -n 2 , verificar a data no início do segundo line (que - sob a suposição razoável de "normalmente" longas linhas - será concluída) e decidir qual metade você quer.

    
por 09.10.2013 / 10:47
1

Obtenha o tamanho do arquivo e divida por 2. Divida isso por 1024 para obter KiB. (Ou 1024 * 1024 para obter MiB, etc.)

((fs = $(stat -c %s logfile) / 2 / 1024))

Ignore e pesquise

dd if=logfile bs=1024 skip=$fs | grep blahblah

Você pode expandir ainda mais isso, se o arquivo de log for muito consistente com a quantidade de dados pr. dia adicionando um valor count= a dd .

((cnt = $(stat -c %s logfile) / 5 / 1024))

dd if=logfile bs=1024 skip=$fs count=$cnt | grep blahblah

Isso canalizaria cnt * 1024 bytes de dados no deslocamento fs * 1024 bytes.

Enrole tudo em um script e faça o piping fora do script para grep, arquivo temporário ou o que você quiser.

    
por 09.10.2013 / 10:50
0

Não está muito claro o que exatamente você quer fazer e o que você quer dizer com o meu "processo". Para arquivos grandes, meu programa interativo favorito é less . Ele lida com arquivos grandes sem problemas. Ele também pode pular para uma porcentagem específica, por exemplo usando 30% . Além disso, você pode pesquisar usando / e ? .

    
por 09.10.2013 / 11:08

Tags