「国民の祝日」データを年ごとに切り分ける

先ほど(執筆時)興味深いツールが公開された。GitHub上の「RoliSoft/WSL-Distribution-Switcher」は、WSLのLinuxディストリビューションをDocker Hubを使って置き換えるスクリプトである。Pythonベースで記述しており、Debian GNU/LinuxやFedora、CentOS、openSUSEなどに変更できるという。今回は時間の都合で試せなかったが、興味をお持ちの方は是非試してほしい。

さて、内閣府は国民の祝日をWebページ上で公開し、本稿執筆時点では2016年(平成28年)から2018年(平成30年)までのデータをCSVデータとして公開中である。これは国民の祝日に関する法律の一部を改正する法律(平成26年法律第43号)を施行し、2016年から「山の日(8月11日)」が加わったためだ。

問題はそのCSVファイルである。Microsoft Excel上で単に祝日名称と祝日月日を入力し、そのままCSV形式で出力したと思われるが、X方向に2016年、2017年、2018年と並んでいるため、1行に3年分の祝日が並ぶという通常ではあまり考えられないものだった。2017年2月前後の公開直後は一部のSNSで話題になったため、ご存じの方も多いことだろう。

残念ながら筆者は、その時のCSVファイルを破棄しているため、お見せすることはできないが、その後も改善が進んで、「2016-01-01,元日」と1行ごとのデータに置き換えられた。だが、Webサーバーのディレクトリ名は「shukujitsu」、CSVファイル名は「syukujitsu.csv」。"shu"と"syu"が混じるなど目を伏せたくなるようなミスも多いものの、改善する姿勢がある点は評価したい。

CSVファイル「syukujitsu.csv」をMicrosoft Excelで開いた状態。3年分の祝日が記述されている

だが、3年分のファイルがひとまとめになると、他のシェルスクリプトで使う際も加工が必要になるだろう。そこで今回は「国民の祝日」CSVデータを年ごとに切り分けるシェルスクリプトを作成した。いつもどおり任意のテキストエディターに以下の内容を入力し、必要に応じて出力先のパスなどを変更してから、「chmod」コマンドなどで実行権限を与えて動作を確認してほしい。

 #!/bin/bash

 URL=http://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv
 OUT2016="/mnt/c/Users/kaz/Desktop/2016.csv"
 OUT2017="/mnt/c/Users/kaz/Desktop/2017.csv"
 OUT2018="/mnt/c/Users/kaz/Desktop/2018.csv"

 if [ -f $OUT2016 ]; then
    rm $OUT2016 $OUT2017 $OUT2018
 fi

 Array=($(curl -s $URL | iconv -f SJIS -t UTF8))
 for Obj in ${Array[@]}; do
    case $Obj in
        2016* )
            echo $Obj >>$OUT2016 ;;
        2017* )
            echo $Obj >>$OUT2017 ;;
        2018* )
            echo $Obj >>$OUT2018 ;;
    esac
    let I++
 done

本シェルプログラムを実行すると、Webサーバー上から内閣府が用意したCSVファイルを取得し、「2016.csv」「2017.csv」「2018.csv」の3ファイルをCSV形式のまま、デスクトップに出力する。詳しくは後述するものの、出力するファイルの文字コードはUTF-8に変換しているため、そのままではExcelで開くことはできない。

シェルスクリプトを実行すると、Windows 10のデスクトップに「2016.csv」「2017.csv」「2018.csv」の3ファイルを出力する

lessで「2016.csv」ファイルを開いた状態

それでは、順にシェルスクリプトの内容を紹介しよう。まず3行目でダウンロードするCSVファイルのURL、4~6行目で出力ファイル名を変数で定義し、8~10行目で一部の出力ファイルが残っている場合は、すべて削除している。続いて12行目ではcurlを使ってCSVファイルを取得し、文字コードを変換するiconvを使って変換した内容を配列「Array」に格納した。

13行~23行目のforは配列Arrayに格納した数だけループを回し、格納した文字列の先頭が「2016」なら15~16行目、文字列の先頭が「2017」なら17~18行目、文字列の先頭が「2018」なら19~20行目に振り分けて、そのまま内容を出力している。

前述のように出力したCSVファイルをBash上(UTF-8)ではなく、Windows 10上のExcel上(シフトJIS)で使う場合は、12行目の「Array=($(curl -s $URL | iconv -f SJIS -t UTF8))」を「Array=$(curl -s $URL)」に変更して、iconvの処理を削除すればよい。

iconvの処理を取り除くとシフトJISのまま出力するため、Excelで開いても文字化けは発生しない

阿久津良和(Cactus)