0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

個人的な備忘録まとめ:祝日データの自動取得と管理に関するスクリプト

Last updated at Posted at 2024-10-20

はじめに

このブログでは、祝日データを自動で取得し、管理するためのシェルスクリプトの実装方法について詳しく説明します。

具体的には、CSVファイルのバックアップ、ダウンロード、文字コード変換、ファイルサイズの検証、祝日の数の確認などの処理を行います。

これにより、祝日データの取得を自動化し、エラーが発生した場合には不要なファイルを削除する機能を追加することで、より堅牢なスクリプトに仕上げました。

前提条件

この記事は、個人の備忘録となっており、以下の関連記事の続きの記事となっています。

追加処理:各処理が失敗したパターンで残ったファイルについて削除

#!/bin/bash

# 環境変数をセット
SYUKUJITSU_FILE="syukujitsu.csv"
BACKUP_FILE="backup_syukujitsu.csv"
NEW_FILE="new_syukujitsu.csv"
LOG_FILE="syukujitsu.log"
DOWNLOAD_URL="https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv"

# 今ある祝日のCSVファイルをコピーする(バックアップファイルを作成する)
if cp "${SYUKUJITSU_FILE}" "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップを作成しました。" > "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップの作成に失敗しました。" > "${LOG_FILE}"
    exit 1
fi

# CSVファイルを取得する
if curl -o "${NEW_FILE}" "${DOWNLOAD_URL}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 新しい祝日CSVファイルを取得しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 祝日CSVファイルの取得に失敗しました。" >> "${LOG_FILE}"
    if rm -f "${BACKUP_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

# 文字コードをSJISからUTF-8に変換する
if iconv -f SHIFT_JIS -t UTF-8 "${NEW_FILE}" > "${NEW_FILE}.utf8"; then
    mv "${NEW_FILE}.utf8" "${NEW_FILE}"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 文字コードの変換に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 文字コードの変換に失敗しました。" >> "${LOG_FILE}"
    if rm -f "${BACKUP_FILE}" "${NEW_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルと新しいファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

# 新しいCSVファイルとバックアップファイルのサイズを比較
if [ "$(stat -c%s "${NEW_FILE}")" -ge "$(stat -c%s "${BACKUP_FILE}")" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルサイズの検証に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルサイズが小さくなっています。" >> "${LOG_FILE}"
    if rm -f "${BACKUP_FILE}" "${NEW_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルと新しいファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

# バックアップファイルを削除
if rm "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップファイルを削除しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップファイルの削除に失敗しました。" >> "${LOG_FILE}"
    if rm -f "${BACKUP_FILE}" "${NEW_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルと新しいファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

# 新しいファイルをsyukujitsu.csvにリネーム
if mv "${NEW_FILE}" "${SYUKUJITSU_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルのリネームに成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルのリネームに失敗しました。" >> "${LOG_FILE}"
    if rm -f "${NEW_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要な新しいファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 新しいファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') - 処理が完了しました。" >> "${LOG_FILE}"
exit 0

追加処理:ファイルサイズが小さくなった場合

ファイルサイズが小さくなった場合に、今年の年を求め、new_syukujitsu.csvとbackup_syukujitsu.csvの中に今年の祝日の数を比較して、同じであれば正常、異なる場合は異常として処理します。

# 新しいCSVファイルとバックアップファイルのサイズを比較
if [ "$(stat -c%s "${NEW_FILE}")" -ge "$(stat -c%s "${BACKUP_FILE}")" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルサイズの検証に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルサイズが小さくなっています。" >> "${LOG_FILE}"

    # 現在の年を取得
    CURRENT_YEAR=$(date '+%Y')

    # NEW_FILEとBACKUP_FILEの祝日の数を比較
    NEW_FILE_HOLIDAYS=$(grep -c "${CURRENT_YEAR}" "${NEW_FILE}")
    BACKUP_FILE_HOLIDAYS=$(grep -c "${CURRENT_YEAR}" "${BACKUP_FILE}")

    if [ "${NEW_FILE_HOLIDAYS}" -eq "${BACKUP_FILE_HOLIDAYS}" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 祝日の数が一致しました。正常とみなします。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 祝日の数が一致しません。異常とみなします。" >> "${LOG_FILE}"
        if rm -f "${BACKUP_FILE}" "${NEW_FILE}"; then
            echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルと新しいファイルを削除しました。" >> "${LOG_FILE}"
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なファイルの削除に失敗しました。" >> "${LOG_FILE}"
        fi
        exit 1
    fi
fi

このスクリプトの変更点は以下の通りです。
年の取得: CURRENT_YEAR に現在の年を設定します。
祝日の数の比較: grep コマンドを用いて、それぞれのファイルに含まれる現在の年の行数(祝日の数)をカウントします。
祝日の数の一致を判定: NEW_FILE と BACKUP_FILE に含まれる祝日の数が一致する場合、正常と判断してそのまま進めます。異なる場合は、異常として不要なファイルを削除します。

これにより、ファイルサイズが小さくなった場合でも、祝日のデータが正常であればそのまま処理を続行することが可能になります。

全体修正版コード

#!/bin/bash

# 環境変数をセット
SYUKUJITSU_FILE="syukujitsu.csv"
BACKUP_FILE="backup_syukujitsu.csv"
NEW_FILE="new_syukujitsu.csv"
LOG_FILE="syukujitsu.log"
DOWNLOAD_URL="https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv"

# 今ある祝日のCSVファイルをコピーする(バックアップファイルを作成する)
if cp "${SYUKUJITSU_FILE}" "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップを作成しました。" > "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップの作成に失敗しました。" > "${LOG_FILE}"
    exit 1
fi

# CSVファイルを取得する
if curl -o "${NEW_FILE}" "${DOWNLOAD_URL}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 新しい祝日CSVファイルを取得しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 祝日CSVファイルの取得に失敗しました。" >> "${LOG_FILE}"
    if rm -f "${BACKUP_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

# 文字コードをSJISからUTF-8に変換する
if iconv -f SHIFT_JIS -t UTF-8 "${NEW_FILE}" > "${NEW_FILE}.utf8"; then
    mv "${NEW_FILE}.utf8" "${NEW_FILE}"
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 文字コードの変換に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - 文字コードの変換に失敗しました。" >> "${LOG_FILE}"
    if rm -f "${BACKUP_FILE}" "${NEW_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルと新しいファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

# 新しいCSVファイルとバックアップファイルのサイズを比較
if [ "$(stat -c%s "${NEW_FILE}")" -ge "$(stat -c%s "${BACKUP_FILE}")" ]; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルサイズの検証に成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルサイズが小さくなっています。" >> "${LOG_FILE}"

    # 現在の年を取得
    CURRENT_YEAR=$(date '+%Y')

    # NEW_FILEとBACKUP_FILEの祝日の数を比較
    NEW_FILE_HOLIDAYS=$(grep -c "${CURRENT_YEAR}" "${NEW_FILE}")
    BACKUP_FILE_HOLIDAYS=$(grep -c "${CURRENT_YEAR}" "${BACKUP_FILE}")

    if [ "${NEW_FILE_HOLIDAYS}" -eq "${BACKUP_FILE_HOLIDAYS}" ]; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 祝日の数が一致しました。正常とみなします。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 祝日の数が一致しません。異常とみなします。" >> "${LOG_FILE}"
        if rm -f "${BACKUP_FILE}" "${NEW_FILE}"; then
            echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なバックアップファイルと新しいファイルを削除しました。" >> "${LOG_FILE}"
        else
            echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要なファイルの削除に失敗しました。" >> "${LOG_FILE}"
        fi
        exit 1
    fi
fi

# バックアップファイルを削除
if rm "${BACKUP_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップファイルを削除しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - バックアップファイルの削除に失敗しました。" >> "${LOG_FILE}"
    exit 1
fi

# 新しいファイルをsyukujitsu.csvにリネーム
if mv "${NEW_FILE}" "${SYUKUJITSU_FILE}"; then
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルのリネームに成功しました。" >> "${LOG_FILE}"
else
    echo "$(date '+%Y-%m-%d %H:%M:%S') - ファイルのリネームに失敗しました。" >> "${LOG_FILE}"
    if rm -f "${NEW_FILE}"; then
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 不要な新しいファイルを削除しました。" >> "${LOG_FILE}"
    else
        echo "$(date '+%Y-%m-%d %H:%M:%S') - 新しいファイルの削除に失敗しました。" >> "${LOG_FILE}"
    fi
    exit 1
fi

echo "$(date '+%Y-%m-%d %H:%M:%S') - 処理が完了しました。" >> "${LOG_FILE}"
exit 0

フロー処理の流れ

1. 環境変数のセット
   |
   V
2. 祝日CSVファイルのバックアップ
   | 
   |-- 成功  ログにバックアップを作成しました。」と記録  次のステップへ
   |
   |-- 失敗  ログにバックアップの作成に失敗しました。」と記録  スクリプト終了

3. 新しい祝日CSVファイルのダウンロード
   |
   |-- 成功  ログに新しい祝日CSVファイルを取得しました。」と記録  次のステップへ
   |
   |-- 失敗  ログに祝日CSVファイルの取得に失敗しました。」と記録
   |             |
   |             |-- バックアップファイルを削除  ログに不要なバックアップファイルを削除しました。」と記録
   |             |
   |             |-- スクリプト終了

4. 文字コードの変換
   |
   |-- 成功  ログに文字コードの変換に成功しました。」と記録  次のステップへ
   |
   |-- 失敗  ログに文字コードの変換に失敗しました。」と記録
   |             |
   |             |-- 不要なバックアップファイルと新しいファイルを削除  ログに記録
   |             |
   |             |-- スクリプト終了

5. 新しいCSVファイルとバックアップファイルのサイズを比較
   |
   |-- 成功  ログにファイルサイズの検証に成功しました。」と記録  次のステップへ
   |
   |-- 失敗  ログにファイルサイズが小さくなっています。」と記録
   |             |
   |             |-- 現在の年を取得
   |             |
   |             |-- NEW_FILEとBACKUP_FILEの祝日の数を比較
   |             |
   |             |-- 一致  ログに祝日の数が一致しました正常とみなします。」と記録  次のステップへ
   |             |
   |             |-- 不一致  ログに祝日の数が一致しません異常とみなします。」と記録
   |                           |
   |                           |-- 不要なバックアップファイルと新しいファイルを削除  ログに記録
   |                           |
   |                           |-- スクリプト終了

6. バックアップファイルの削除
   |
   |-- 成功  ログにバックアップファイルを削除しました。」と記録  次のステップへ
   |
   |-- 失敗  ログにバックアップファイルの削除に失敗しました。」と記録  スクリプト終了

7. 新しいファイルをsyukujitsu.csvにリネーム
   |
   |-- 成功  ログにファイルのリネームに成功しました。」と記録
   |
   |-- 失敗  ログにファイルのリネームに失敗しました。」と記録
   |             |
   |             |-- 不要な新しいファイルを削除  ログに記録
   |             |
   |             |-- スクリプト終了

8. 処理が完了しましたとログに記録

まとめ

このスクリプトを使用することで、祝日データを自動で管理し、万が一のエラーにも対応できるようになります。今後も、スクリプトの改善や新しい機能の追加を行っていく予定です。ぜひ、実際に試してみてください。

おまけ:個人メモです。

syukujitsu.csvが存在するかどうかを判定し、存在しない場合は代替ファイルから祝日データを取得する処理を実装しています。

#!/bin/bash

# 環境変数をセット
HOLIDAYS_FILE="$HOME/syukujitsu.csv"
ALTERNATE_FILE="/path/to/alternate/syukujitsu.csv"  # 代替ファイルのパスを指定

# syukujitsu.csvの存在を確認
if [ ! -f "$HOLIDAYS_FILE" ]; then
    echo "$HOLIDAYS_FILE が見つかりません。代替ファイルを使用します。"
    HOLIDAYS_FILE="$ALTERNATE_FILE"  # 代替ファイルを使用
fi

# 今日の日付を取得
TODAY=$(date +%Y/%-m/%-d)

# 祝日判定
if grep -q "^$TODAY," "$HOLIDAYS_FILE"; then
    holiday="holiday"
else
    holiday=""
fi

# 結果の表示
if [ -n "$holiday" ]; then
    echo "$TODAY は祝日です。"
else
    echo "$TODAY は祝日ではありません。"
fi

スクリプトの処理内容

環境変数のセット:
HOLIDAYS_FILE に祝日データが保存されているファイルのパスを指定。
ALTERNATE_FILE に代替ファイルのパスを指定。

ファイルの存在確認:
syukujitsu.csv が存在しない場合、ALTERNATE_FILE を使用する旨のメッセージを表示し、HOLIDAYS_FILE を代替ファイルに設定。

今日の日付の取得:
TODAY に現在の日付を「YYYY/MM/DD」の形式で格納。

祝日判定:
grep コマンドを使用して、HOLIDAYS_FILE に今日の日付が存在するかをチェックし、祝日の場合は変数 holiday に "holiday" をセット。

0
1
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
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?