西海岸より

つらつらざつざつと

sqliteファイルのテーブルを一括でCSV出力して、他のsqliteと差分比較

sqliteファイルの差分を取りたいと思い、無料であまり良いツールが無かったので、sqliteファイルをCSV出力するshellを自分で組み、その出力結果をdiffツールで比較することを考えた。
(Macを想定してます)

sqliteファイルをCSV出力するshell

  • ソース (sqliteToCsv.sh)
    • Mac上で動作確認
#!/bin/bash

usage() {
  echo "Usage: sh sqliteToCsv.sh [sqlitepath] ([outputdir, default=output])"
  exit 1
}

###### parameter
# sqlite path
SQLITE_PATH=""
if [ "$1" != "" ]; then
  SQLITE_PATH=$1
else
  usage
fi

# output directory
OUTPUT_DIR="output"
if [ "$2" != "" ]; then
  OUTPUT_DIR=$2
fi
mkdir -p $OUTPUT_DIR


###### sqlite to csv
for TARGET in `sqlite3 $SQLITE_PATH ".tables"`
do
  OUTPUT_FILE="$OUTPUT_DIR/$TARGET.csv"

  DATA_NUM=`sqlite3 $SQLITE_PATH "select count(*) from $TARGET"`
  if [ $DATA_NUM -lt 1 ]; then
    echo "Table:$TARGET DataNum:${DATA_NUM}"
    echo "No data" > $OUTPUT_FILE
  else
    CLM_NUM=`sqlite3 -header $SQLITE_PATH "select * from $TARGET" \
            | awk 'BEGIN{FS="|"}{if (NR==1) print NF}'`
    echo "Table:$TARGET DataNum:${DATA_NUM} \
ColNum:${CLM_NUM}"
    if [ $CLM_NUM -lt 1 ]; then
      echo "No columns" > $OUTPUT_FILE
    else 
      # sort 
      ORDER_RULE="1"
      for (( a=2; a<=$CLM_NUM; a++ ))
      do
        ORDER_RULE="${ORDER_RULE},$a"
      done
      sqlite3 -header -separator "," $SQLITE_PATH "select * from $TARGET \
order by $ORDER_RULE" > $OUTPUT_FILE
    fi
  fi
done

if [ "$OUTPUT_FILE" = "" ]; then
  echo "No tables..."
else
  echo "Done."
fi
  • 使い方
    • sqliteのファイルパスと、CSVを出力するディレクトリ(省略可)を指定するのみ。
Usage: sh sqliteToCsv.sh [sqlitepath] ([outputdir, default=output])

shellの中で、全部のカラムをorder byでソートしている理由は、後ほど差分比較するため。
これが無いと差分がとれません。

出力CSVの差分比較

GUIのdiffツールといえば、Xcodeに付属しているFileMerge(Spotlightで入力すると出てきます)
か、diffMergeというフリーのツール。個人的には、ディレクトリを含む多数ファイルの差分比較をとるときには、diffMergeを使うことが多いです。

これで、CSV出力ツールで出力したディレクトリを指定して差分を取ることが可能になります。

ソース取得先

githubにサンプル含めアップしてます

入門bash 第3版

入門bash 第3版