郵便番号辞書 Mozc形式作成手順


# Mozc向け郵便番号辞書の生成スクリプト
MOZCのユーザー辞書形式で出力する手順とスクリプトです。
スクリプトはMITライセンスです。
[phoepsilonix/japanese-zip-code-dictionary](https://github.com/phoepsilonix/japanese-zip-code-dictionary/)
```shell
wget -nc https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip
wget -nc https://www.post.japanpost.jp/zipcode/dl/jigyosyo/zip/jigyosyo.zip
```
```shell
unzip -o ken_all.zip
unzip -o jigyosyo.zip
```
```shell
uconv -x '::[ [:^Katakana:] & [:^Hiragana:] & [:^Han:] & [^ー・「」、，（）]]  Fullwidth-Halfwidth; ::[\p{Nl}] Latin-ASCII;' -f cp932 -t UTF-8 KEN_ALL.CSV > KEN_ALL_UTF8.CSV
uconv -x '::[ [:^Katakana:] & [:^Hiragana:] & [:^Han:] & [^ー・「」、，（）]]  Fullwidth-Halfwidth; ::[\p{Nl}] Latin-ASCII;' -f cp932 -t UTF-8 JIGYOSYO.CSV > JIGYOSYO_UTF8.CSV 
```

```awk:ken_all-convert-mozc-dictionary.awk
BEGIN{
    FS=","
    f=0
}
{
    gsub( "\"", "", $0 );
    gsub(/以下に掲載がない場合|.*くる場合|.*村一円/,"",$9);
    if (f==$3) {
        next;
    } else
    {
        f=0
    }
    if (($9 ~ /（.+、/ || $9 ~ /（.*・/) && f==0) f = $3;
    $9 = gensub(/([^（]*)（.*/, "\\1", "G", $9)
    c[0] = gensub(/第?([０-９0-9]+)地割(.*)/, "\\3", "G" ,$9)
}
{
    if (!a[$3,$7,$8,c[0]]++) {
        if(c[0] ~ /、/) {
            if (c[0] ~ /町/) {
                split(c[0], chou, "町")
                split(chou[2], array, "、")
                chou[1] = chou[1] "町"
            } else {
            split(c[0], array, "、")
            chou[1] = ""
        }
        for (x in array) {
            print substr($3, 1, 3) "-" substr($3,4,4) "\t" $7 $8 chou[1] array[x] "\t" "地名" "\t"
        }
        } else {
            print substr($3, 1, 3) "-" substr($3,4,4) "\t" $7 $8 c[0] "\t" "地名" "\t"
        }
    }
}
```

```awk:jigyosyo-convert-mozc-dictionary.awk
BEGIN{
    FS=","
    f=0
}
{
    gsub( "\"", "", $0 );
    gsub(/以下に掲載がない場合|.*くる場合|.*村一円/,"",$9);
    if (f==$8) {
        next;
    } else
    {
        f=0
    }
    if (($7 ~ /（.+、/ || $7 ~ /（.*・/) && f==0) f = $8;
}
{
    gsub("，",",",$3)
    gsub("（","(",$3)
    gsub("）",")",$3)
    gsub("㈱","(株)",$3)
    if (!a[$8,$4,$5,$6,$3]++) {
        print substr($8, 1, 3) "-" substr($8,4,4) "\t" $4 $5 $6 " " $3 "\t" "組織" "\t"
    }
}
```

```shell
awk -f ken_all-convert-mozc-dictionary.awk KEN_ALL_UTF8.CSV > KEN_ALL.txt
awk -f jigyosyo-convert-mozc-dictionary.awk JIGYOSYO_UTF8.CSV > JIGYOSYO.txt
```

# Mozc本家のPythonスクリプトを使う場合
## 必要なファイルの準備
```sh
mkdir -p dictionary
cd dictionary
wget https://github.com/google/mozc/raw/refs/heads/master/src/dictionary/gen_zip_code_seed.py
wget https://github.com/google/mozc/raw/refs/heads/master/src/dictionary/zip_code_util.py
cd ..
wget -nc https://www.post.japanpost.jp/zipcode/dl/kogaki/zip/ken_all.zip
wget -nc https://www.post.japanpost.jp/zipcode/dl/jigyosyo/zip/jigyosyo.zip
unzip -o ken_all.zip
unzip -o jigyosyo.zip
```
## スクリプトの実行
```sh
PYTHONPATH="$PYTHONPATH:$PWD" python dictionary/gen_zip_code_seed.py --zip_code=KEN_ALL.CSV | awk '{FS="\t"}{print $1 "\t" $5 "\t" "地名" "\t"}'|sort -u > KEN_ALL.tsv
PYTHONPATH="$PYTHONPATH:$PWD" python dictionary/gen_zip_code_seed.py --jigyosyo=JIGYOSYO.CSV | awk '{FS="\t"}{print $1 "\t" $5 "\t" "組織" "\t"}'|sort -u > JIGYOSYO.tsv 
```
## スクリプトの実行 その２
PYTHONPATHを指定せず、利用する場合。
シェルで実行する場合には、`from dictionary `を取り除いても、問題ありません。gen_zip_code_seed.pyと同じフォルダにあるものが、優先されて探されるからです。
一つ前のやり方は、bazelから呼び出している場合に、sandbox内の同じ場所にzip_code_util.pyがないための処置だと思われます。(bazelの設定ファイルにimport = ["."],を追加することで、回避できる問題のようです。ただし、ポリシー的に一貫性を保つために、採用されていないそうです。)
```sh
sed -e 's/^from dictionary //' -i dictionary/gen_zip_code_seed.py
python dictionary/gen_zip_code_seed.py --zip_code=KEN_ALL.CSV | awk '{FS="\t"}{print $1 "\t" $5 "\t" "地名" "\t"}'|sort -u > KEN_ALL.tsv
python dictionary/gen_zip_code_seed.py --jigyosyo=JIGYOSYO.CSV | awk '{FS="\t"}{print $1 "\t" $5 "\t" "組織" "\t"}'|sort -u > JIGYOSYO.tsv 
```

## 番外編
### bazelコマンドで生成する
Mozcソース下での操作になります。
ただし、この場合は都道府県と事業所が１つのファイルになってしまいます。
```sh
cd mozc/src
bazel build dictionary:zip_code_data --config oss_linux
ls -l bazel-bin/dictionary/zip_code.tsv
cat bazel-bin/dictionary/zip_code.tsv | awk '{FS="\t"}{print $1 "\t" $5 "\t" "地名" "\t"}'|sort -u > ZIP_CODE.TSV
```

### bazelコマンドで生成したスクリプトで作成する
PRした際に、教えてもらった方法です。
ただし実行するには、./bazel-bin/dictionary/の下に生成される複数のファイルが必要になります。
```sh
bazel build dictionary:gen_zip_code_seed --config oss_linux
./bazel-bin/dictionary/gen_zip_code_seed --help
```
```sh
./bazel-bin/dictionary/gen_zip_code_seed --zip_code=KEN_ALL.CSV | awk '{FS="\t"}{print $1 "\t" $5 "\t" "地名" "\t"}'|sort -u > KEN_ALL.tsv
./bazel-bin/dictionary/gen_zip_code_seed --jigyosyo=JIGYOSYO.CSV | awk '{FS="\t"}{print $1 "\t" $5 "\t" "組織" "\t"}'|sort -u > JIGYOSYO.tsv 
```

# その他、Mozc関連記事
[Mozc を応援するいくつかの方法](https://zenn.dev/komatsuh/articles/91def2bc633a8d)

[大概のLinuxで使えそうな日本語入力(Flatpak版Fcitx5-Mozc)](https://zenn.dev/phoepsilonix/articles/flatpak-mozc)
[UbuntuでMozcの新しいバージョンをビルドするには](https://zenn.dev/phoepsilonix/articles/0c492a22a3c9d0)
[Mozcをオフラインでビルドするには？](https://zenn.dev/phoepsilonix/articles/mozc-offiline-build)

[DockerでビルドしたMozcをUbuntu 22.04 LTSにインストールする](https://zenn.dev/ikuya/articles/aa69fd1009b773)
[Ubuntu 20.04 LTS/20.10でFcitx5を使用する](https://zenn.dev/ikuya/articles/f42da50d670a8562a12e)