Pesquisa binária por uma linha falhada

1

git tem bisect run para descobrir qual revisão foi introduzida por um erro.

Eu tenho um arquivo grande (100 GB) e pelo menos uma das linhas é ruim, mas o programa que eu tenho que verificar não me diz qual linha.

As linhas são registros, então eu posso escrever uma pesquisa binária usando head e tail e /2 (passando a primeira metade para o programa, e se não houver erros, a segunda metade), e com base nisso dividindo a metade novamente.

Mas existe uma ferramenta automatizada que pode fazer isso sem minha intervenção (semelhante a git bisect run )?

    
por Ole Tange 16.10.2013 / 14:31

1 resposta

1

você pode usar split para dividir um arquivo em várias partes e tem uma opção para dividir apenas as linhas:

$ ls
bigfile
$ split -n l/2 bigfile
$ ls
bigfile xaa xab

isso só faz sentido se o arquivo puder ser dividido e organizado em linhas, o que é válido apenas para arquivos de texto.

Com isso, você pode criar facilmente sua própria ferramenta de bifurcação, por exemplo algo como o seguinte:

#!/bin/sh

TESTPROG=$1
DATA=$2

usage() {
    echo "usage: $0 <testprog> <datafile>"
    echo "     will bisect <datafile> to the single line where <testprog> exits with '0'"
    exit 1
}

if [ ! -x "${TESTPROG}" ]; then  usage; fi
if [ ! -e "${DATA}" ]    ; then  usage; fi

BISECTDIR=$(mktemp -d)

splitfiles() {
    split -e -n l/2 $1 ${BISECTDIR}/$2bisect_
    echo ${BISECTDIR}/$2bisect_*
}
cleanup() {
    rm -rf "${BISECTDIR}"
    exit 0
}

i=1
while [ $(head -2 "${DATA}" | wc -l) -gt 1 ]; do
  echo "testing: ${DATA} $(head -2 "${DATA}" | wc -l)" 1>&2
  files=$(splitfiles ${DATA} ${i})
  count=$(echo $files | awk '{print NF}')
  if [  ${count} -lt 2 ]; then
      cat $files
      cleanup
  fi
  DATA=""
  for f in $files; do
          if ${TESTPROG} "${f}" 1>/dev/null 2>/dev/null; then
          DATA="${f}"
          break
      fi
  done
  i=$(( i+1 ))
done

cleanup

ressalva: isso colocará todos os dados divididos em /tmp (mude a definição de BISECTDIR se você não gostar disso); Isso também limpará os arquivos de dados divididos ao final. então você pode precisar de muito espaço ...

    
por 16.10.2013 / 14:43