0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FileMakerからのMigrationで改行とタイムスタンプの処理

Last updated at Posted at 2024-09-26

FileMakerからMySQLへのMigration、および、FileMakerのオブジェクトをS3にアップロードするの続きになる。

FileMakerのテキストフィールド内の改行は0x0B (VT:垂直タブ)で繰り返しフィールドの区切り文字は0x1D。このままでは困るので他システムに移行しても使えるよう0x0D, 0x0A (CR/LF)に変換する。また、クラウド用にタイムスタンプをUTCに変換する。

処理はMySQLにインポートする前にアップロードしたCSVファイルをコピーしているシェルスクリプトがあるのでその中で行う。

FileMakerの出力と同じダブルクォート付きCSVでタイムスタンプで0秒が省略されるところに対応している。大きなファイルでサーバーがハングアップするので改良しているがこれでも1ヶ月程度のデータが限界っぽい(Claude 3.5に聞いた結果を貼り付けてるだけですが検証済みです)。

#!/bin/bash

DATE=$(<date.txt)
sh find_new_file.sh -v "$DATE" temp/csv/ > result.txt
RESULT=$(<result.txt)
if [ -z "$RESULT" ]; then
  exit 0
fi

cd temp/csv

# 変換とコピーを行う関数
convert_and_copy() {
    local input_file="$1"
    local output_file="/var/lib/mysql-files/$(basename "$input_file")"
    
    LC_ALL=en_US.UTF-8 awk '
    BEGIN {
        FS=OFS=","
        FPAT="([^,]+)|(\"[^\"]+\")"
    }
    function is_timestamp(str) {
        gsub(/^"|"$/, "", str)
        return str ~ /^[0-9]{4}(\/|-)[0-9]{2}(\/|-)[0-9]{2} [0-9]{1,2}:[0-9]{2}(:[0-9]{2})?$/
    }
    function convert_timestamp(str) {
        orig_str = str
        gsub(/^"|"$/, "", str)
        gsub(/-/, "/", str)
        if (str !~ /:[0-9]{2}$/) {
            str = str ":00"
        }
        cmd = "date -d\"" str " JST\" -u \"+%Y-%m-%d %H:%M:%S\""
        cmd | getline utc_time
        close(cmd)
        return (orig_str ~ /^".*"$/) ? "\"" utc_time "\"" : utc_time
    }
    {
        for (i = 1; i <= NF; i++) {
            if (is_timestamp($i)) {
                $i = convert_timestamp($i)
            }
        }
        # 0x1Dが1つ以上連続する部分を1つの改行に置換
        gsub(/\x1D+/, "\r\n")
        # VTを改行に変換
        gsub(/\v/, "\r\n")
        print
    }
    ' "$input_file" > "$output_file"
    
    echo "Converted and copied: $input_file"
}

# 並列処理の管理
MAX_JOBS=4  # 同時に実行するジョブの最大数
CURRENT_JOBS=0

# 全ての.csvファイルに対して変換とコピーを実行
for file in *.csv; do
    if [ -f "$file" ]; then
        # 同時実行ジョブ数が最大数に達しているか確認
        while [ $CURRENT_JOBS -ge $MAX_JOBS ]; do
            sleep 1
            CURRENT_JOBS=$(jobs -r | wc -l)
        done
        
        # 新しいサブシェルでファイル処理を実行
        (
            convert_and_copy "$file"
        ) &
        
        CURRENT_JOBS=$((CURRENT_JOBS + 1))
    fi
done

# 全てのバックグラウンドジョブの完了を待つ
wait

echo "All files have been processed."

# MySQLにインポート
mysql --defaults-file=~/.my.cnf < csvimp.sql

# 現在のディレクトリをホームディレクトリに変更
cd ~/

# 日付を更新
date +%Y%m%d%H%M > date.txt
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?