カタカタブログ

SIerで働くITエンジニアがカタカタした記録を残す技術ブログ。Java, Oracle Database, Linuxが中心です。たまに数学やデータ分析なども。

Windowsでzip化したファイルをLinuxで展開すると文字化け

Windowsで日本語を含むフォルダやファイルをzipし、それをLinux上のunzipコマンドで展開すると日本語が文字化けした。
ググると、結構情報がヒットするので、割とメジャーな問題のよう。Webを参考にしつつ、対応方法をまとめてみた。

なお当環境はCent OS 6.5で検証している。

原因

unzipコマンドがデフォルトでUTF-8で展開してしまっているらしい。そのため、SJISで圧縮されたファイルをUTF-8で展開してしまっているため文字化けが発生しているよう。

例えば、WinZipとかで以下のような日本語を含むフォルダ・ファイルをzip化すると、Linuxで展開したときに文字化けする。

f:id:osn_th:20140909080853p:plain

Linux (CentOS6)で展開

unzipのバージョンは6.00

UnZip 6.00 of 20 April 2009, by Info-ZIP.  Maintained by C. Spieler.

$ ls -l test.zip
-rw-r--r--. 1 dev dev 272  9月  8 16:51 2014 test.zip
$ unzip test.zip
Archive:  test.zip
   creating: test/??????????/
extracting: test/??????????/?-????.txt 

対策

対応策は主に以下の2点がある。

  • SJIS対応できるようunzipにパッチを適用する
  • convmvコマンドでUTF-8展開されたファイルをSJISに変換する

結論から言うと、convmvコマンドは実行してみたものの別の化け方をしてしまい、解消されなかった。そのため、unzipにパッチを適用することで解消することを確認した。

unzipにSJIS対応パッチ適用

基本的に以下のページを参考にした。
http://memorosa.blogspot.jp/2011/04/unzipsjis.html

unzipのrpm入手

[root@localhost unzip-ja]# wget ftp://mirror.switch.ch/pool/4/mirror/redhat/linux/enterprise/5Server/en/os/SRPMS/unzip-5.52-3.el5.src.rpm
--2014-09-08 22:18:16--  ftp://mirror.switch.ch/pool/4/mirror/redhat/linux/enterprise/5Server/en/os/SRPMS/unzip-5.52-3.el5.src.rpm
           => `unzip-5.52-3.el5.src.rpm'mirror.switch.ch をDNSに問いあわせています... 130.59.10.36
mirror.switch.ch|130.59.10.36|:21 に接続しています... 接続しました。
anonymous としてログインしています... ログインしました!
==> SYST ... 完了しました。    ==> PWD ... 完了しました。
==> TYPE I ... 完了しました。  ==> CWD (1) /pool/4/mirror/redhat/linux/enterprise/5Server/en/os/SRPMS ... 完了しました。
==> SIZE unzip-5.52-3.el5.src.rpm ... 1160296
==> PASV ... 完了しました。    ==> RETR unzip-5.52-3.el5.src.rpm ... 完了しました。
長さ: 1160296 (1.1M) (確証はありません)
100%[======================================>] 1,160,296    424K/s 時間 2.7s   
2014-09-08 22:18:22 (424 KB/s) - `unzip-5.52-3.el5.src.rpm' へ保存終了 [1160296]
[root@localhost unzip-ja]# ls -l
合計 1136
-rw-r--r--. 1 root root 1160296  9月  8 22:18 2014 unzip-5.52-3.el5.src.rpm

パッチ入手

[root@localhost unzip-ja]# wget 'http://ebuild.gentoo.gr.jp/open.php?mode=download&type=files&cat=app-arch&app=unzip&arg=unzip-5.52-ubuntuja.patch&visible=' -O unzip-5.52-sjis.patch
--2014-09-08 22:19:22--  http://ebuild.gentoo.gr.jp/open.php?mode=download&type=files&cat=app-arch&app=unzip&arg=unzip-5.52-ubuntuja.patch&visible=ebuild.gentoo.gr.jp をDNSに問いあわせています... 124.35.85.89
ebuild.gentoo.gr.jp|124.35.85.89|:80 に接続しています... 接続しました。
HTTP による接続要求を送信しました、応答を待っています... 200 OK
長さ: 特定できません [text/plain]
`unzip-5.52-sjis.patch' に保存中
    [ <=>                                   ] 9,025       --.-K/s 時間 0s     
2014-09-08 22:19:22 (463 MB/s) - `unzip-5.52-sjis.patch' へ保存終了 [9025]
[root@localhost unzip-ja]# ls -l
合計 1148
-rw-r--r--. 1 root root 1160296  9月  8 22:18 2014unzip-5.52-3.el5.src.rpm
-rw-r--r--. 1 root root    9025  9月  8 22:19 2014 unzip-5.52-sjis.patch

rpmインストール

[root@localhost unzip-ja]# rpm -ivh unzip-5.52-3.el5.src.rpm
警告: unzip-5.52-3.el5.src.rpm: ヘッダ V3 DSA/SHA1 Signature, key ID 37017186: NOKEY
   1:unzip                  警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
警告: ユーザ brewbuilder は存在しません - root を使用します
警告: グループ brewbuilder は存在しません - root を使用します
########################################### [100%]

★警告が出ているがrootでインストールしたので問題なし

rootユーザのHOMEディレクトリ以下のrpmbuildにunzipができたことを確認

[root@localhost unzip-ja]# ls -ld ~/rpmbuild/
drwxr-xr-x. 4 root root 4096  9月  9 06:37 2014 /root/rpmbuild/
[root@localhost unzip-ja]# find ~/rpmbuild/
/root/rpmbuild/
/root/rpmbuild/SPECS
/root/rpmbuild/SPECS/unzip.spec
/root/rpmbuild/SOURCES
/root/rpmbuild/SOURCES/unzip552.tar.gz
/root/rpmbuild/SOURCES/unzip-5.52-near-4GB.patch
/root/rpmbuild/SOURCES/unzip-5.52-toctou.patch
/root/rpmbuild/SOURCES/unzip542-rpmoptflags.patch
/root/rpmbuild/SOURCES/unzip-5.52-long-filename.patch
/root/rpmbuild/SOURCES/unzip-5.52-near-4GB2.patch
/root/rpmbuild/SOURCES/unzip-5.52-open.patch
/root/rpmbuild/SOURCES/unzip-5.52-ret.patch
/root/rpmbuild/SOURCES/unzip-5.51-link-segv2.patch
/root/rpmbuild/SOURCES/unzip-5.51-link-segv.patch

パッチファイル配置

[root@localhost SPECS]# cp ~/unzip-ja/unzip-5.52-sjis.patch /root/rpmbuild/SOURCES/
[root@localhost SPECS]# ls -l /root/rpmbuild/SOURCES/unzip-5.52-sjis.patch
-rw-r--r--. 1 root root 9025  9月  9 06:56 2014 /root/rpmbuild/SOURCES/unzip-5.52-sjis.patch

unzip.spec編集

[root@localhost unzip-ja]# cd /root/rpmbuild/SPECS/
[root@localhost SPECS]# cp -p unzip.spec unzip.spec.org
[root@localhost SPECS]# vi unzip.spec

Release: 3%{?dist} -> Release: 3%{?dist}.1ja に変更
Patch12: unzip-5.52-sjis.patch を追記
%patch12 -p1 -b .sjis を追記

[root@localhost SPECS]# diff unzip.spec unzip.spec.org
4c4
< Release: 3%{?dist}.1ja
---
> Release: 3%{?dist}
17d16
< Patch12: unzip-5.52-sjis.patch
43d41
< %patch12 -p1 -b .sjis

ビルド

[root@localhost SPECS]# rpmbuild -ba unzip.spec
(・・・略)
書き込み完了: /root/rpmbuild/SRPMS/unzip-5.52-3.el6.1ja.src.rpm
書き込み完了: /root/rpmbuild/RPMS/x86_64/unzip-5.52-3.el6.1ja.x86_64.rpm
書き込み完了: /root/rpmbuild/RPMS/x86_64/unzip-debuginfo-5.52-3.el6.1ja.x86_64.rpm
実行中(%clean): /bin/sh -e /var/tmp/rpm-tmp.rPHJjh
+ umask 022
+ cd /root/rpmbuild/BUILD
+ cd unzip-5.52
+ rm -rf /root/rpmbuild/BUILDROOT/unzip-5.52-3.el6.1ja.x86_64
+ exit 0
[root@localhost SPECS]# echo $?
0

★ビルド成功

rpmが作成されたことを確認

[root@localhost SPECS]# ls -l /root/rpmbuild/RPMS/x86_64
合計 484
-rw-r--r--. 1 root root 142384  9月  9 06:57 2014 unzip-5.52-3.el6.1ja.x86_64.rpm
-rw-r--r--. 1 root root 348396  9月  9 06:57 2014 unzip-debuginfo-5.52-3.el6.1ja.x86_64.rpm

unzipインストール

[root@localhost SPECS]# rpm -Uvh /root/rpmbuild/RPMS/x86_64/unzip-5.52-3.el6.1ja.x86_64.rpm
準備中...                ########################################### [100%]
パッケージ unzip-6.0-1.el6.x86_64 (unzip-5.52-3.el6.1ja.x86_64 より新しいもの) は既にインストールされています。

すでに6.00が入っていたので、強制上書きインストール

[root@localhost SPECS]# rpm -ivh --force /root/rpmbuild/RPMS/x86_64/unzip-5.52-3.el6.1ja.x86_64.rpm
準備中...                ########################################### [100%]
   1:unzip                  ########################################### [100%]

★成功

5.52になったことを確認

[root@localhost SPECS]# unzip
UnZip 5.52 of 28 February 2005, by Info-ZIP.  Maintained by C. Spieler.

パッチ適用済みunzip検証

$ unzip test.zip
Archive:  test.zip
   creating: test/あいうえお/
 extracting: test/あいうえお/てすと.txt 

★文字化けせずに解凍できた!

Ubuntuだと標準unzipコマンドがSJIS対応されているよう

ちなみにUbuntuだとパッチを当てなくともデフォルトのunzipコマンドに-Oオプションでsjis(cp932)を指定すると回避できる。

Ubuntuのunzipのバージョン

UnZip 5.52 of 28 February 2005, by Ubuntu. Original by Info-ZIP.
  • Oオプションを付与して解凍
$ unzip -O cp932 test.zip
Archive:  test.zip
   creating: test/あいうえお/
extracting: test/あいうえお/てすと.txt

★デフォルトのunzipで文字化けせずに解凍できる

convmvで展開後に解消

convmvというコマンドにて、展開後に直す方法もあるらしいが、結論から言うと当環境ではこのコマンドで文字化けは解消しなかった。そのときのメモを残しておく。

convmvのrpm入手

[root@localhost unzip]# wget http://rpm.pbone.net/index.php3/stat/4/idpl/16984585/dir/redhat_el_5/com/convmv-1.15-1.el5.rfx.noarch.rpm.html
[root@localhost unzip]# ls -l convmv-1.15-1.el5.rfx.noarch.rpm
-rw-r--r--. 1 root root 25212  9月  8 17:40 2014 convmv-1.15-1.el5.rfx.noarch.rpm

convmvインストール

[root@localhost unzip]# rpm -ivh convmv-1.15-1.el5.rfx.noarch.rpm
警告: convmv-1.15-1.el5.rfx.noarch.rpm: ヘッダ V3 DSA/SHA1 Signature, key ID 6b8d79e6: NOKEY
準備中...                ########################################### [100%]
   1:convmv                 ########################################### [100%]
[root@localhost unzip]# echo $?
0
[root@localhost unzip]# which convmv
/usr/bin/convmv

convmv実行

[root@localhost unzip]# unzip test.zip
Archive:  test.zip
   creating: test/??????????/
extracting: test/??????????/?-????.txt
[root@localhost unzip]# convmv -r -f cp932 -t utf8 test
Starting a dry run without changes...
mv "test/????????/?-????.txt"   "test/????????/?-鯊鱚.txt"
mv "test/????????"      "test/鱆鴣鴦鬪鯀"
No changes to your files done. Use --notest to finally rename the files.

★別の文字化けになってしまっている

結論

Cent OS 6の環境ではunzipのパッチを当てて解消する方が無難か。

以上