【Linux】シェルでCSVからSQLを作成するサンプル

シェルスクリプト(shell)でcsvファイルを読み込んで、そこからSQL(UPDATE文)を作成するサンプルを作りました。

なぜこんなものを作ったんかというと、いつもならエクセルを使ってサッとSQLを作成するのですが、今使っているのOSはlinuxでしかもCUIだったこともあり、エクセルを使わずにSQLを効率的に作るために作成しました。

今回のサンプルはテーブルのカラムが3カラムと固定されているため、流用する場合は各々のスキーマ似合う形でソースを修正する必要があるのでご注意ください。

 

実行例

ドライランの実行例
  load_csv.sh -d [csvパス] [テーブル名] [ 1ファイルの記載限界値] 
  load_csv.sh -d ./test.csv table1 1000 
通常の実行例
  load_csv.sh -d [csvパス] [テーブル名] [ 1ファイルの記載限界値] 
  load_csv.sh -d  ./test.csv table1 1000

 

サンプルソース

#!/bin/bash

# point
# 引数を動的に受け取る
# CSVファイルを読み込む-> SQLを作成する

echo "========== 【SQLファイル作成処理 START】=========="
echo "---------- 引数を動的に設定 START ----------"
# 引数が渡されているかのチェック
if [ ! -n "$1" ]; then
    echo "引数がありません。"
    exit 1
fi

PARAMS=()
DRY_RUN_FLAG=0
# 引数の数だけ繰り返す
for i in `seq 1 ${#}`
do
    # 第一引数をチェック
    if [ ${1} = "-d" ]; then
        DRY_RUN_FLAG=1
    else
        # 引数をパラメータとしてセット
        PARAMS+=($1)
    fi
    # 次の引数に移る
    shift
done

# パラメータの要素数をチェック
# 実行パラメータのチェック(パラメータの個数が2個以上3個以下)
if [ ${#PARAMS[@]} -lt 2 -o ${#PARAMS[@]} -gt 3 ]; then
    echo "パラメータの指定が間違っています(引数は2個以上3個以下です。)" 1>&2
    exit 1
fi

# 変数の初期化、パラメータの設定
UPDATE_SQL="update_query_:count.sql"
# SELECT_SQL="select_query_:count.sql"
CSV_FILE=${PARAMS[0]}
TABLE_NAME=${PARAMS[1]}
if [ "${PARAMS[2]}" != "" ]; then
    LINE_SIZE=${PARAMS[2]}
else
    LINE_SIZE=0
fi
echo "---------- 引数を動的に設定 END ----------"

echo "---------- ファイルのチェック START ----------"
if [ ! -f ./$CSV_FILE ]; then
    echo "作業ディレクトリ直下に${CSV_FILE}のファイルが存在しません。" 1>&2
    exit 1
fi
echo "---------- ファイルのチェック END ----------"

echo "---------- CSV読込+SQLファイルの作成 START ----------"
SQL=""
CSV_LINE_COUNTER=0
# CSVファイルの内容は以下の通り
#   id,name,age
#   1,test1,20
#   2,テスト2,30
#   3,"てすと3",40
#   4,test4,20
#   5,test5,20
#   6,test6,20
#   7,test7,20
#   8,test8,20
#   9,test9,20
#   10,test10,20

# 1行目をカラム名としてセットし、2行目以降を値としてSQL文を作成
if [ $DRY_RUN_FLAG -eq 1 ]; then
    # 動作確認
    while read line; do
    if [ $CSV_LINE_COUNTER -eq 0 ]; then
      COLUMN_1=`echo ${line} | cut -d , -f 1`
      COLUMN_2=`echo ${line} | cut -d , -f 2`
      COLUMN_3=`echo ${line} | cut -d , -f 3`
    else
      DATA_1=`echo ${line} | cut -d , -f 1`
      DATA_2=`echo ${line} | cut -d , -f 2`
      DATA_3=`echo ${line} | cut -d , -f 3`
    fi
    # SQL文の作成
    SQL="${SQL}UPDATE ${TABLE_NAME} SET ${COLUMN_2}=\"${DATA_2}\", ${COLUMN_3}=\"${DATA_3}\" WHERE ${COLUMN_1}=${DATA_1};\\n"
    # カウンターを1つ進める
    CSV_LINE_COUNTER=`expr $CSV_LINE_COUNTER + 1`

    done < ./$CSV_FILE
    (
      echo $SQL
    ) | echo ${SQL}
else
  SQL_LINE_COUNTER=1
    FILE_NUMBER=1
    # 処理実行
    while read line; do
    if [ $CSV_LINE_COUNTER -eq 0 ]; then
      COLUMN_1=`echo ${line} | cut -d , -f 1`
      COLUMN_2=`echo ${line} | cut -d , -f 2`
      COLUMN_3=`echo ${line} | cut -d , -f 3`
    else
      DATA_1=`echo ${line} | cut -d , -f 1`
      DATA_2=`echo ${line} | cut -d , -f 2`
      DATA_3=`echo ${line} | cut -d , -f 3`

      # SQL文の作成
      SQL="UPDATE ${TABLE_NAME} SET ${COLUMN_2}=\"${DATA_2}\", ${COLUMN_3}=\"${DATA_3}\" WHERE ${COLUMN_1}=${DATA_1};"
      # ファイル名を置換して、連番のファイル名を設定
      FILE_NAME=`echo $UPDATE_SQL | sed -e "s/:count/$FILE_NUMBER/" `
      # SQL分をファイルに記載
      echo $SQL >> ./$FILE_NAME

      if [ $LINE_SIZE -eq 0 -o $SQL_LINE_COUNTER -lt $LINE_SIZE ]; then 
        # 1ファイルの記載限界未満の超えてない場合
        SQL_LINE_COUNTER=`expr $SQL_LINE_COUNTER + 1`
        #   echo "    ${CSV_LINE_COUNTER}件処理完了"
      else
        # 1ファイルの記載限界以上の超えた場合
        SQL_LINE_COUNTER=1
        FILE_NUMBER=`expr $FILE_NUMBER + 1`
      fi
    fi
    # カウンターを1つ進める
    CSV_LINE_COUNTER=`expr $CSV_LINE_COUNTER + 1`

    done < ./$CSV_FILE
  fi
echo "---------- CSV読込+SQLファイルの作成 END ----------"
echo "========== 【SQLファイル作成処理 END】=========="

 



投稿日:2018-10-11    更新日:2018-10-11

[スポンサーリンク]

サイト内検索
プロフィール

プロフィール

[Name : じゃぶじゃぶ(@jbjb_2019)]
都内で社内SEをしているおじさん。
仕事で得られる知識だけでは限界を感じ、 WEBの勉強がてらITブログを開始。
サーバからWEBサイトまでフルスクラッチで開発しました。
現在は勉強のモチベーションを保つために活用中。
興味があることを雑記的に書いていきます。

[スポンサーリンク]

[スポンサードリンク]