Unzip の日本語ファイル名の取り扱いについて

Windows XP上で作成したZIPファイルを Unix上の unzip コマンドで展開すると、 中のファイルの日本語ファイル名が化けてしまうことがあります。

$ unzip -l hoge.zip 
Archive:  hoge.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  11-06-2010 17:46   В┘В.txt
---------                     -------
        0                     1 file

調べてみると、unzipコマンドはファイル名の8bit目が1の場合に おかしな変換をすることがあるみたい。 この辺の解説は以下のページが詳しいです。

対策としては、上記ページにあるように Ext_ASCII_TO_Native マクロを上書きして コード変換しないようにしても良いのですが、 どうせだったらOS上で使ってるエンコーディングに変換して欲しいものです。 そんなpatchを探していたら、見付けたのがコレ。

unzip にこの patch を当ててやると、 「-O/-I でZIPファイル中のファイル名のエンコーディングを指定すると、 iconv()で現在のlocaleの設定に変換してくれる」という動作をしてくれます。 例えば、Windowsの「圧縮フォルダ」で作成したZIPファイルの場合は、 中の日本語ファイル名のエンコーディングが Shift_JIS になっているので、 こんな感じになります。

$ unzip -Ocp932 -l hoge.zip 
Archive:  hoge.zip
  Length      Date    Time    Name
---------  ---------- -----   ----
        0  11-06-2010 17:46   ほげ.txt
---------                     -------
        0                     1 file
(化けてない)

$ echo $LC_CTYPE 
ja_JP.UTF-8
$ unzip -Ocp932 -l hoge.zip | nkf --guess
UTF-8 (LF)
(UTF-8に変換されてる)

$ export LC_CTYPE=ja_JP.eucJP
$ unzip -Ocp932 -l hoge.zip | nkf --guess
EUC-JP (LF)
(localeを ja_JP.eucJP にすると、EUC-JPに変換される)

ちなみに、FreeBSD の ports では上記patch はすでに取り込み済です。

-O と -I をどう使い分けるのか?

大雑把に言うと、

  • DOS/Windows上で作成したZIPファイルを扱う時は -O
  • それ以外のOS(UNIX等)では -I

という使い分けをします。どっちで作成されたかの確認をするには、 zipinfoコマンドを使うと良いです。

zipinfo hoge.zip 
Archive:  hoge.zip
Zip file size: 114 bytes, number of entries: 1
-rw----     2.0 ntf        0 b- stor 10-Nov-06 17:46 В┘В.txt
1 file, 0 bytes uncompressed, 0 bytes compressed:  0.0%

このファイル名の行の第3カラムが「ntf」や「fat」となっていたら DOS/Windows上で作成されたものなので -Oを使い、 「unx」となっていたら -I を使う、という感じです。

スポンサーリンク
スポンサーリンク:

フォローする