AWK入門:CSVファイルからLOAD DATA文を作成する

スポンサーリンク
AWK入門:CSVファイルからLOAD DATA文を作成する ノウハウ
AWK入門:CSVファイルからLOAD DATA文を作成する
この記事は約9分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、AWKでCSVファイルからLOAD DATA文を作成する方法についてご紹介します。

スポンサーリンク

背景

AWKでCSVヘッダーを参照して、load data 文を作成する機会があったので、そのときの内容を備忘としてのこしました。

作成ファイル一覧

下記のファイルを作成しました。

gen_load_data_sql.sh
gen_head_value.awk
gen_set_value.awk

gen_load_data_sql.sh

#!/bin/bash

csvPath=test.csv

head=$(head -n 1 ${csvPath} | awk -f gen_head_value.awk)

setValue=$(head -n 1 ${csvPath} | awk -f gen_set_value.awk)

cat << EOS > load_test.sql
LOAD DATA
  LOCAL
  INFILE '${csvPath}'
    INTO TABLE sample
  FIELDS TERMINATED BY ','
           ENCLOSED BY '"'
   LINES TERMINATED BY '\n'
         (${head})
     SET ${setValue}
;
EOS

gen_head_value.awk

BEGIN {
    FS=",";
    OFS=",";
}
{
    for(i=1; i<=NF; i++) {
        printf("@%d%s", \
            i, \
            (i!=NF) ? OFS : "" );
    }
}

gen_set_value.awk

BEGIN {
    FS=",";
    OFS=",";
}
{
    for(i=1; i<=NF; i++) {
        value=($i=="uuid") ? "UUID_TO_BIN(@" i ")" : "@" i;
        printf("`%s`=%s%s%s", \
            $i, \
            value, \
            (i!=NF) ? OFS : "",
            ORS);
    }
}

実行結果

下記のtest.csvを用意します。

id,uuid,value,created_at,updated_at
1,2D04153F-02B9-4E4B-9327-03B3B196CBD6,840,2023-11-26 15:35:40,2023-11-27 15:35:40
2,717058B8-2866-42C6-ACB5-D5BB359A26D2,394,2023-11-26 15:35:40,2023-11-28 15:35:40
3,0BC6EB72-41A5-4C2D-9937-E93F5BC5DCE9,783,2023-11-26 15:35:40,2023-11-29 15:35:40

下記のファイルが出力されていれば成功です。

下記のコマンドを実行します。

bash gen_load_data_sql.sh

下記のファイルが出力されていれば成功です。

load_test.sql

ファイル内容は下記になります。

LOAD DATA
  LOCAL
  INFILE 'test.csv'
    INTO TABLE sample
  FIELDS TERMINATED BY ','
           ENCLOSED BY '"'
   LINES TERMINATED BY '\n'
         (@1,@2,@3,@4,@5)
     SET `id`=@1,
`uuid`=UUID_TO_BIN(@2),
`value`=@3,
`created_at`=@4,
`updated_at`=@5
;

解説

gen_head_value.awk

このawkスクリプトは、CSV形式のファイルを処理して、各行のフィールド(列)に対して特定の形式で番号をつけて出力するものです。以下にコードの各部分の解説を示します。

BEGIN {
    FS=",";
    OFS=",";
}
  • BEGIN ブロック: プログラムが実行される前に初期化を行うためのブロックです。
  • FS=",": FS (Field Separator) をカンマに設定します。これはCSV形式のファイルで各列がカンマで区切られていることを意味します。
  • OFS=",": OFS (Output Field Separator) をカンマに設定します。これにより、printfでデフォルトの出力フィールドセパレータを使用する際に、出力される各フィールドの間にカンマが挿入されます。
{
    for(i=1; i<=NF; i++) {
        printf("@%d%s", \
            i, \
            (i!=NF) ? OFS : "" );
    }
    print "";  # 改行を追加して次の行に移行
}
  • 通常のブロック: 各行に対する処理を行います。
  • for(i=1; i<=NF; i++): 各フィールドに対して繰り返し処理を行います。
  • printf("@%d%s", i, (i!=NF) ? OFS : "" ): 各フィールドに対して、「@番号」の形式で出力します。三項演算子 (i!=NF) ? OFS : "" は、最後のフィールド以外の場合にはカンマ OFS を追加し、最後のフィールドの場合には何も追加しないようにしています。
  • print "";: 各行の処理が終わったら、改行を追加して次の行に移行します。

例えば、入力が “A,B,C” のようなCSV行であれば、このスクリプトは “@1,@2,@3” という形式で出力します。

gen_set_value.awk

このawkスクリプトは、CSV形式のファイルを処理して、各行のフィールド(列)に対して特定の条件で処理を行いながら出力するものです。以下にコードの各部分の解説を示します。

BEGIN {
    FS=",";
    OFS=",";
}
  • BEGIN ブロック: プログラムが実行される前に初期化を行うためのブロックです。
  • FS=",": FS (Field Separator) をカンマに設定します。これはCSV形式のファイルで各列がカンマで区切られていることを意味します。
  • OFS=",": OFS (Output Field Separator) をカンマに設定します。これにより、printfでデフォルトの出力フィールドセパレータを使用する際に、出力される各フィールドの間にカンマが挿入されます。
{
    for(i=1; i<=NF; i++) {
        value=($i=="uuid") ? "UUID_TO_BIN(@" i ")" : "@" i;
        printf("`%s`=%s%s%s", \
            $i, \
            value, \
            (i!=NF) ? OFS : "",
            ORS);
    }
}
  • 通常のブロック: 各行に対する処理を行います。
  • for(i=1; i<=NF; i++): 各フィールドに対して繰り返し処理を行います。
  • value=($i=="uuid") ? "UUID_TO_BIN(@" i ")" : "@" i;: 各フィールドの値に対して条件分岐を行い、uuid の場合は UUID_TO_BIN(@i) に変換し、それ以外の場合は元の値 @i を保持します。
  • printf("%s=%s%s%s", $i, value, (i!=NF) ? OFS : "", ORS);: 各フィールドに対して、「フィールド名=変換後の値」の形式で出力します。フィールドの間には OFS で指定されたカンマが挿入され、行末には ORS で指定された改行が追加されます。

例えば、入力が “id,uuid,value” のようなCSV行であれば、このスクリプトは “id=1, uuid=UUID_TO_BIN(@2), value=@3″ といった形式で出力します。

gen_load_data_sql.sh

このBashスクリプトは、与えられたCSVファイル (test.csv) からMySQLのLOAD DATAコマンドを生成し、その結果をload_test.sqlファイルに書き込みます。以下に各部分の解説を示します。

  1. csvPath=test.csv: CSVファイルのパスを変数 csvPath に設定しています。
  2. head=$(head -n 1 ${csvPath} | awk -f gen_head_value.awk): CSVファイルの先頭行(ヘッダー)を取得し、awkスクリプト gen_head_value.awk を適用して、MySQLのLOAD DATAコマンドで使用するヘッダーの部分を生成し、変数 head に格納しています。
  3. setValue=$(head -n 1 ${csvPath} | awk -f gen_set_value.awk): CSVファイルの先頭行を取得し、awkスクリプト gen_set_value.awk を適用して、MySQLのSET句の部分を生成し、変数 setValue に格納しています。
  4. cat << EOS > load_test.sql: ヒアドキュメントを使用して、load_test.sql ファイルを生成するための開始を示します。
  5. LOAD DATA...: MySQLのLOAD DATAコマンドを指定しています。ここで、${head}${setValue}にはそれぞれヘッダーとSET句の内容が挿入されます。
  6. EOS: ヒアドキュメントの終了を示しています。

簡単にまとめると、このスクリプトは与えられたCSVファイルからMySQLのLOAD DATAコマンドを生成し、それをload_test.sqlファイルに書き込んでいます。生成されたload_test.sqlファイルは、MySQLに対してデータの一括挿入を行う際に使用できます。

おわりに

今日は、AWKでCSVファイルからLOAD DATA文を作成する方法についてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました