2012年09月29日

【Linux】文字化けで解凍不能なZIPファイル用「unzip-cp932」初版リリース

 頻度は少ないもののLinux機でZIPファイルを解凍しようとしても、その中の圧縮ファイルのフォルダ名が文字化けしていることが起因となり、結果としてファイルを解凍出来ないことがある。これらは、Windows環境下同士なら問題にならないことなので、日常的にWindows機を利用している人なら取り敢えずはそちらで対処しUSBメモリー等でLinux機に持ってくれば済むことなのだが、当方の様に端末も含めLinux中心に利用している者にとってはとても困ることになる。そんなことで、Ubuntu環境ではcp932のパス名対応のオプションバッチを当てたunzipが存在するものの当方の利用しているCentOS6様のRPMパッケージはない様だったので、Pythonの標準ライブラリのみでcp932対応のunzipもどきを作成して試た。

 ここで公開の「unzip-cp932」はpythonで作成しているので、今時のLinuxであれば初めからpythonはinstallされているので、同名でファイルをコピペで作成後、1行目のpythonのinstall位置を修正し、「chmod +x ./unzip-cp932」でファイルに実行権限を付与とするだけで実行出来る様になる。

 利用法は以下の通りで、画面出力はunzipにいくらか真似て試たが、今の所、コマンドオプションとしては、ZIPファイル名(必須)と解凍先のディレクトリ位置(省略時はカレントディレクトリ)のみを有効としているだけで、オリジナルのunzipとは程遠い点はご勘弁頂きたい。気になる方は、GPLライセンスに従い、思い通りに改善し公開頂きたい。




[mire@localhost ~]$ ./unzip-cp932 /media/HD-PCTX5/2010/03/Photos20100305_from_suzu.zip ~/test_a
filepath: /media/HD-PCTX5/2010/03/Photos20100305_from_suzu.zip
inflating: 霧島登山/集合写真a.jpg
inflating: 霧島登山/集合写真b.jpg
inflating: 霧島登山/20100305/01.jpg
inflating: 霧島登山/20100305/02.jpg
inflating: 霧島登山/20100305/03.jpg
<中略>
inflating: 霧島登山/20100305/12.jpg
inflating: 霧島登山/20100305/MOVIE/01.mp4
inflating: 霧島登山/20100305/MOVIE/02.mp4

[mire@localhost ~]$
 また、最初のコマンド引数としてファイルを指定しなかったり、ヘルプを意図する「--help」や「--hh」を指定した場合には以下の様な説明書きを表示する様にしている。利用方法の確認には、そうして頂きたい。



[mire@localhost ~]$ ./unzip-cp932 --help
unzip-cp932 0.0.1 of 2012-09-28. Maintained by Mire in Japan. Send bug
reports using http://pythonlife.seesaa.net/article/294731873.html

USAGE: unzip-cp932 <a zip file> [<path for extract files into>]

利用方法: unzip-cp932 <zipファイル> [<解凍先ディレクトリ>]

※ 実行には最低で解凍対象のZIPファイル1つを指定する必要があります。
 オプションとして解凍先ディレクトリを続けて指定することが出来ますが、
unzipコマンドの様な多様なオプションは一切実装していませんし、解凍後の
ファイル中の文字コード自体は当前圧縮時のままです。中身のコード変換は
nkf辺りがその守備範囲です。そこらをあたって下さい。
 また、解凍先に解凍ファイルと同じ名のファイルがある場合は、今の所
既存ファイルの上書き喪失を回避する為、同名ファイル解凍しない仕様です。
一つでも「 already exists.」と表示されたなら<解凍先ディレクトリ>に
新規の解凍先名を指定して試て下さい。ZIPの中身全てが解凍出来る筈です。
 尚、これは公開義務等のGPLライセンスを満たす範囲で改良頂けます。
その場合の改変内容公開は不具合連絡同様に下記の当方Blogへのコメントで
済ませて頂いて構いません。
http://pythonlife.seesaa.net/article/294731873.html
[mire@localhost ~]$


 これを実現している「unzip-cp932」のソースコードは以下の通り(但し、最新公開版は次稿の【Linux】文字化けで解凍不能なZIPファイル用「unzip-cp932」第4版リリース)。
            ~/unzip-cp932


#!/usr/bin/python2.6
#-*- coding: utf-8 -*-
u"""
unzip-cp932: unzip an arcive file that created with Windows Japanese Edition

USAGE: unzip-cp932 <zip file> <path for extract files into>

※ Windows日本語版で作成したZIPファイルはアーカイブ情報の文字コードがcp932である
ことで、Linux上では正しく解凍出来ない問題が生じる。このソースコードはcp932を
uncode化し、その問題を手当てしたものである。
"""
__author__ = "Mire in Japan"
__date__ = "2012-09-28"
__version__ = '0.0.1'
__copyright__ = 'Copyright (c) 2012-09-28 Mire'
__license__ = 'GPL'
__url__ = 'http://pythonlife.seesaa.net/article/294731873.html '

from sys import argv #コマンドラインオプションの取得
from zipfile import ZipFile #ZIP形式の圧縮ファイルの操作
from os.path import split as fsplit #ファイルパスの分離
from os.path import exists, join #ファイルパスの存否判定
from os import makedirs #ファイルパスの新規作成

if (len(argv)>=2 and exists(argv[1]) and #コマンド引数指定があり第1引数が実在ファイルか
not (argv[1]=='--help' or argv[1]=='-hh')): #第1引数がヘルプオプション指定でなければ、
print 'filepath:', argv[1] # その引数を画面出力
# 第2引数:解凍先 #
if len(argv)>=3: # さらに第2引数があるなら
dir = argv[2] # それを解凍先ディレクトリとし
else: # ないなら
dir = None # Noneを当てる
# ZipFileオブジェクト生成 #
z = ZipFile(argv[1], 'r') # 第1引数指定のZIPファイルを読込モードで開き
# ZIP内ファイル名リストの取得 #
names = z.namelist() # 指定したZIPファイルのファイル名一覧を取得

for name in names: # その一覧から1つずつファイル名を取り出し
unicode_name = unicode(name, 'cp932') # それをunicode文字列に変換
print 'inflating:', unicode_name # unicode文字列に変換したものを画面表示
p, f = fsplit(unicode_name) # ファイル名をディレクトリとファイル名に分割
# 書出し先パス文字列の生成 #
if dir==None: # 解凍先指定がないなら
path = p # ZIPファイル内の個別ファイルのパスをパスに
else: # 解凍先ディレクトリ指定があるなら
path = join(dir, p) # 指定解凍先ディレクトリ配下の
# 書込先のディレクトリ文字列生成
# 個別ファイルの解凍先フルパス名 #
filepath = join(path, f) # 個別ファイルの解凍先フルパス名を生成
# 書出し先ディレクトリの整備 #
if not exists(path): # そのディレクトリが存在しないなら
makedirs(path) # 解凍時のエラー回避の為、それを作成
# 解凍先の既存ファイル上書き対策 #
if exists(filepath): # 解凍先に同名ファイルがあれば
print u'\"%s\" already exists.' % ( # その旨表示しその解凍処理を飛ばす
filepath)
else: # ないなら、以下の個別ファイルの解凍処理を実施
# 個別ファイルの解凍先への解凍処理本体 #
x = z.open(name, 'r') # ZIPファイル内の中身ファイルを開く
fpo = open(filepath, 'wb') # unicode文字列化したファイルの書込みを
d = x.read(256) # ZIPファイル内の個別ファイルを256biteずつ読取り
while d: # 中身がある限り
fpo.write(d) # 解凍して行く
d = x.read(256) # 次の256バイトを読取り、ループ
x.close() # ZIPファイル内の中身ファイルを閉じる
fpo.close() # unicode文字列化したファイルを閉じる

z.close() # ZIPファイルのZipFileオブジェクトを閉じる
print
else:
# 引数等不適合時の利用方法案内 #
print u""" %s %s of %s. Maintained by %s. Send bug
reports using %s

USAGE: unzip-cp932 <a zip file> [<path for extract files into>]

利用方法: unzip-cp932 <zipファイル> [<解凍先ディレクトリ>]

※ 実行には最低で解凍対象のZIPファイル1つを指定する必要があります。
 オプションとして解凍先ディレクトリを続けて指定することが出来ますが、
unzipコマンドの様な多様なオプションは一切実装していませんし、解凍後の
ファイル中の文字コード自体は当前圧縮時のままです。中身のコード変換は
nkf辺りがその守備範囲です。そこらをあたって下さい。
 また、解凍先に解凍ファイルと同じ名のファイルがある場合は、今の所
既存ファイルの上書き喪失を回避する為、同名ファイル解凍しない仕様です。
一つでも「 already exists.」と表示されたなら<解凍先ディレクトリ>に
新規の解凍先名を指定して試て下さい。ZIPの中身全てが解凍出来る筈です。
 尚、これは公開義務等の%sライセンスを満たす範囲で改良頂けます。
その場合の改変内容公開は不具合連絡同様に下記の当方Blogへのコメントで
済ませて頂いて構いません。
%s""" % (fsplit(argv[0])[1], __version__, __date__, __author__
, __url__, __license__, __url__)

利用手順

  1.  このテキストをコピペで、「unzip-cp932」と言うファイル名のファイルを作成。
    • Linuxの場合拡張子「.py」は必ずしも必要ではないので、利用時の便宜を考え省略した。
  2.  1行目の「#!/usr/bin/python2.6」を自己のLinux環境のpythonへのpathに合わせる。
    • Pythonへのpathは「whereis python」の実行で調べることが出来る。通常は「/usr/bin」配下、別途installしたなら「/usr/local/bin」配下の「python2.x」の様なpython実行ファイルのフルパスが最適。
  3.  そのファイルに実行モードを設定
    • 単に「chmod +x unzip-cp932」とするだけ
  4.  必要なら環境変数PATHの及ぶディレクトリに移動またはコピー
    • 環境変数PATHの及ぶディレクトリは「printenv | grep PATH」で判る。当方の場合は、通常、「/usr/local/bin」とすることが多い。
posted by Mire at 13:28 | Comment(1) | TrackBack(0) | Pythonプログラミング | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
助かりました。ありがとう
Posted by tt at 2012年12月12日 06:34
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック
月額見放題1,000円開始キャンペーンバナー(画像ありver)
紺碧の艦隊 ルパン三世 GREAT CHASE クリックプロモーション
<< 2013年01月 >>
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
カテゴリ
タグクラウド
ファン
利用中のオープンソース
最近のコメント
最近の記事
過去ログ
QRコード
レガシーなアプリはいかが?
Dell 法人のお客様ページ
  • 【法人様向け】デル、お得なキャンペーン情報
  • 法人のお客様向け ストレージソリューション
  • 法人のお客様向け ネットワークソリューション
  • 【SOHO法人様向け】デル・オンライン広告限定ページ
  • デル-個人のお客様ページ
  • 【個人のお客様向け】デル・オンライン広告限定ページ
  • オンライン広告限定キャンペーンページ
  • ソフトウェア&周辺機器 パソコン工房
    ツートップインターネットショップ(twotop.co.jp) マウスコンピューター/G-Tune
  • ×

    この広告は1年以上新しい記事の投稿がないブログに表示されております。