• このエントリーをはてなブックマークに追加

はじめに

郵便番号情報は日々,というか月々くらい? 更新されます.そのデータは,次からダウンロードできます:

AjaxZip2 は,「郵便番号 → 住所」な検索に必要なデータ(以下,郵便番号辞書)を,独自の JSON 形式で data ディレクトリにもっています.(HTTP経由でアクセス可能であれば変更は可能.)そして,上記のダウンロードデータを郵便番号辞書に変換するための Perl スクリプト work/csv2jsonzip.pl も準備されていてありがたいです.

ただ,この Perl スクリプトは,大元のデータが存在していることが前提なので,そのデータを取ってくるところから自動でできるといいよね,などと思い,1ステップで更新処理が完了できるようなシェルスクリプトを書いてみました.

仕様

  1. japanpost.jp 上の ken_all.zipjigyosyo.zip の最終更新時刻をチェックする(curl -I で HTTP ヘッダのみチェック)
  2. 前回ダウンロードしたデータの最終更新時刻と異なっていれば,データをダウンロードする
  3. 解凍する
  4. ここで work/csv2jsonzip.pl を実行する
  5. 不要なファイル(ダウンロードファイルとか)を削除する

だいたいこんな感じ.

シェルスクリプト

work/update-data として.

何も考えずにベタに書いちゃってる感じです.エラー時の処理とかもあまり考えていません><

#!/bin/sh
BASEDIR=$(cd $(dirname $0)/.. && pwd)
WORKDIR="$BASEDIR/work"
 
CURL="/usr/bin/env curl"
UNZIP="/usr/bin/unzip -o"
PERL="/usr/bin/env perl"
 
URL_CSV_KENALL="http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip"
URL_CSV_JIGYOSYO="http://www.post.japanpost.jp/zipcode/dl/jigyosyo/zip/jigyosyo.zip"
 
FILENAME_LASTMOD_KENALL=".kenall.lastmod"
FILENAME_LASTMOD_JIGYOSYO=".jigyosyo.lastmod"
 
FILENAME_CSV_KENALL=""
FILENAME_CSV_JIGYOSYO=""
 
 
echo "^[[32mzipcode data is to be updated.^[[0m"
echo "^[[32mdirectory: $WORKDIR^[[0m"
cd $WORKDIR
 
 
echo '^[[32mchecking last-modified of CSV data...^[[0m'
LASTMOD_KENALL=`$CURL -sLI $URL_CSV_KENALL | \grep 'Last-Modified:'     | tail -1 | tr -d '\n' | tr -d '\r'`
LASTMOD_JIGYOSYO=`$CURL -sLI $URL_CSV_JIGYOSYO | \grep 'Last-Modified:' | tail -1 | tr -d '\n' | tr -d '\r'`
LASTMOD_PREV_KENALL=`tail -1 $WORKDIR/$FILENAME_LASTMOD_KENALL 2> /dev/null       | tr -d '\n' | tr -d '\r'`
LASTMOD_PREV_JIGYOSYO=`tail -1 $WORKDIR/$FILENAME_LASTMOD_JIGYOSYO 2> /dev/null   | tr -d '\n' | tr -d '\r'`
 
echo "  ^[[33mkenall (fetch):   $LASTMOD_KENALL^[[0m"
echo "  ^[[33mkenall (prev):    $LASTMOD_PREV_KENALL^[[0m"
echo "  ^[[33mjigyosyo (fetch): $LASTMOD_JIGYOSYO^[[0m"
echo "  ^[[33mjigyosyo (prev):  $LASTMOD_PREV_JIGYOSYO^[[0m"
 
 
echo '^[[32mfetching & extracting CSV data...^[[0m'
if [ "$LASTMOD_KENALL" = "$LASTMOD_PREV_KENALL" ]; then
    echo "^[[32mkenall: not modified, skip.^[[0m"
    echo "^[[32mno need to update.^[[0m"
    exit 0
else
    $CURL -#LO "$URL_CSV_KENALL"
    $UNZIP ken_all.zip
 
    if [ -f "KEN_ALL.CSV" ]; then
        FILENAME_CSV_KENALL="KEN_ALL.CSV"
    else
        FILENAME_CSV_KENALL="ken_all.csv"
    fi
 
    echo $LASTMOD_KENALL > $WORKDIR/$FILENAME_LASTMOD_KENALL
fi
 
if [ "$LASTMOD_JIGYOSYO" = "$LASTMOD_PREV_JIGYOSYO" ]; then
    echo "^[[32mjigyosyo: not modified, skip.^[[0m"
else
    $CURL -#LO "$URL_CSV_JIGYOSYO"
    $UNZIP jigyosyo.zip
 
    if [ -f "JIGYOSYO.CSV" ]; then
        FILENAME_CSV_JIGYOSYO="JIGYOSYO.CSV"
    else
        FILENAME_CSV_JIGYOSYO="jigyosyo.csv"
    fi
 
    echo $LASTMOD_JIGYOSYO > $WORKDIR/$FILENAME_LASTMOD_JIGYOSYO
fi
 
if [ "$FILENAME_CSV_KENALL$FILENAME_CSV_JIGYOSYO" = "" ]; then
    echo "^[[32mno need to update.^[[0m"
    exit 0
fi
 
 
echo '^[[32mgenerating & updating data files...^[[0m'
$PERL csv2jsonzip.pl $FILENAME_CSV_KENALL $FILENAME_CSV_JIGYOSYO
 
 
echo '^[[32mrmeoving needless files...^[[0m'
if [ -f ken_all.zip ];  then
    rm -v ken_all.zip
fi
if [ -f jigyosyo.zip ]; then
    rm -v jigyosyo.zip
fi
rm -v $FILENAME_CSV_KENALL $FILENAME_CSV_JIGYOSYO
 
 
echo '^[[32mdone.^[[0m'
exit 0

実行例

% ./work/update-data
zipcode data is to be updated.
directory: /Users/issm/work/javascript/ajaxzip2/work
checking last-modified of CSV data...
  kenall (fetch):   Last-Modified: Thu, 27 Sep 2012 08:00:18 GMT
  kenall (prev):    
  jigyosyo (fetch): Last-Modified: Thu, 27 Sep 2012 08:01:56 GMT
  jigyosyo (prev):  
fetching & extracting CSV data...
######################################################################## 100.0%
Archive:  ken_all.zip
  inflating: KEN_ALL.CSV             
######################################################################## 100.0%
Archive:  jigyosyo.zip
  inflating: JIGYOSYO.CSV            
generating & updating data files...
ken_all:	KEN_ALL.CSV
北海道  	.......................................... 8246 lines
青森県  	............. 2510 lines
岩手県  	.......... 1937 lines
...
宮崎県  	..... 874 lines
鹿児島県  	........ 1457 lines
沖縄県  	.... 794 lines
jigyosyo:	JIGYOSYO.CSV
北海道  	....... 1267 lines
青森県  	.. 207 lines
岩手県  	. 187 lines
...
宮崎県  	. 170 lines
鹿児島県  	.. 257 lines
沖縄県  	.. 240 lines
module: 	JSON.pm (2.09)
json:   	../data/zip-%s.json
../data/zip-0**.json  .......... 96 files
../data/zip-1**.json  ......... 84 files
../data/zip-2**.json  ......... 88 files
../data/zip-3**.json  .......... 100 files
../data/zip-4**.json  .......... 97 files
../data/zip-5**.json  .......... 98 files
../data/zip-6**.json  .......... 94 files
../data/zip-7**.json  .......... 98 files
../data/zip-8**.json  .......... 100 files
../data/zip-9**.json  .......... 96 files
rmeoving needless files...
ken_all.zip
jigyosyo.zip
KEN_ALL.CSV
JIGYOSYO.CSV
done.

大元(japanpost.jp)の該当 zip ファイルが更新されていなければ何もしません.

% ./work/update-data
zipcode data is to be updated.
directory: /Users/issm/work/javascript/ajaxzip2/work
checking last-modified of CSV data...
  kenall (fetch):   Last-Modified: Thu, 27 Sep 2012 08:00:18 GMT
  kenall (prev):    Last-Modified: Thu, 27 Sep 2012 08:00:18 GMT
  jigyosyo (fetch): Last-Modified: Thu, 27 Sep 2012 08:01:56 GMT
  jigyosyo (prev):  Last-Modified: Thu, 27 Sep 2012 08:01:56 GMT
fetching & extracting CSV data...
kenall: not modified, skip.
no need to update.

なお,以前ダウンロードした zip ファイルの更新時刻情報は,次のように保存されています:

  • work/.kenall.lastmod
  • work/.jigyosyo.lastmod

これらのファイルを削除すれば,次のスクリプト実行時は,必ず zip ファイルのダウンロードを行います.

おわりに

以上,1ステップで AjaxZip2 の郵便番号辞書データの更新を完了できるようなシェルスクリプトを書いてみたお話でした.

現在,デプロイ用 Git リポジトリのフックスクリプトからこれを呼び出すようにしてみていますが,うまく動いてくれているようです.デプロイの頻度を考えれば,特に意識することもなく郵便番号情報を十分新鮮に保てるのではないのかな,などと思ってます.