バイナリ検索に失敗した行

バイナリ検索に失敗した行

gitbisect runどのバージョンでバグが発生したかを調べる必要があります。

大容量ファイル(100GB)がありますが、少なくとも1行以上は不良ですが、確認する必要があるプログラムがどの行かを教えてくれません。

行はレコードなので、headandと(前半をプログラムに渡し、エラーがない場合は後半)を使用してtailバイナリ検索を作成し、それに基づいて後半を再分割できます。/2

しかし、私の介入なしにこれを行うことができる自動化されたツール(と同様git bisect run)はすでにありますか?

ベストアンサー1

以下を使用してファイルを複数の部分に分割することができsplit、行ごとにのみ分割するオプションがあります。

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

これは実際にはファイルにのみ意味があります。できる行に分割して設定すると、テキストファイルでのみ機能します。

これにより、次のような独自の二分法ツールを簡単に作成できます。

#!/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

警告:これを行うと、2等分されたデータがすべて保存されます/tmp(これが気に入らない場合は、BISECTDIRの定義を変更してください)。また、最後に二等分されたデータファイルのみがクリーンアップされます。だから十分なスペースが必要かもしれません...

おすすめ記事