web-dev-qa-db-ja.com

指定されたエンコーディングでZipを解凍します

ファイルを含むZipファイルを取得しました。ファイル名はエンコードされています。それらのファイル名のエンコーディングは知っているが、適切に解凍する方法がまだわからないとしましょう。

これが例 file で、1つのファイル「【SSK字幕组】The Vampire Diaries吸血鬼日记S06E12.ass」が含まれています

使用されているエンコーディングはGB18030(中国語)です。

問題は、適切なエンコードされたファイル名を取得するために、unzipまたは他のCLIユーティリティを使用してFreeBSDでそのファイルを解凍する方法ですか?できる限りのことを試しましたが、結果は決して良くありませんでした。助けてください。

私はOSXで試しました:

MBP1:test 2ge$ bsdtar xf gb18030.Zip
MBP1:test 2ge$ ls
%A1%BESSK%D7%D6Ļ%D7顿The Vampire Diaries %CE%FCѪ%B9%ED%C8ռ%C7S06E12/      gb18030.Zip
MBP1:test 2ge$ cd %A1%BESSK%D7%D6Ļ%D7顿The\ Vampire\ Diaries\ %CE%FCѪ%B9%ED%C8ռ%C7S06E12/
MBP1:%A1%BESSK%D7%D6Ļ%D7顿The Vampire Diaries %CE%FCѪ%B9%ED%C8ռ%C7S06E12 2ge$ ls
%A1%BESSK%D7%D6Ļ%D7顿The Vampire Diaries %CE%FCѪ%B9%ED%C8ռ%C7S06E12.ass*
MBP1:%A1%BESSK%D7%D6Ļ%D7顿The Vampire Diaries %CE%FCѪ%B9%ED%C8ռ%C7S06E12 2ge$ find . | iconv -f gb18030 -t utf-8
.
./%A1%BESSK%D7%D6L抬%D7椤縏he Vampire Diaries %CE%FC血%B9%ED%C8占%C7S06E12.ass 
MBP1:%A1%BESSK%D7%D6Ļ%D7顿The Vampire Diaries %CE%FCѪ%B9%ED%C8ռ%C7S06E12 2ge$ convmv -r -f gb18030 -t utf-8 --notest .
Skipping, already UTF-8: ./%A1%BESSK%D7%D6Ļ%D7顿The Vampire Diaries %CE%FCѪ%B9%ED%C8ռ%C7S06E12.ass
Ready!

Unzipでも同様に試しましたが、同様の問題が発生します。

おかげで、OSX(ターミナル)からSSHを使用して接続しているFREE BSDを試してみました:

# locale
LANG=
LC_CTYPE="C"
LC_COLLATE="C"
LC_TIME="C"
LC_NUMERIC="C"
LC_MONETARY="C"
LC_MESSAGES="C"
LC_ALL=C

まず最初に、中国の名前を適切に表示することです。私が変更され

setenv LC_ALL zh_CN.GB18030
setenv LANG zh_CN.GB18030

次に file をダウンロードし、「ls」を試して適切な文字を表示しますが、運はありません。したがって、適切な結果が得られたときに検証するために、最初の中国語ロケールを解決する必要があると思います。実際には、それを比較できます。これで私も喜んで手伝ってくれる?

26
2ge

エンコードが何であるかを知っている限り、任意のエンコードでZipを解凍するためにUbuntu 16.04で私が行うことは次のとおりです。同じ方法は、広く利用可能なunzipツールにのみ依存しているため、FreeBSDでも機能するはずです。

  1. スペルを間違えないように、エンコーディングの正確な名前を再確認します。 https://www.iana.org/assignments/character-sets/character-sets.xhtml

  2. 走るだけ

    $ unzip -O <encoding> <filename> -d <target_dir>
    

    または

    $ unzip -I <encoding> <filename> -d <target_dir>
    

    ここの指示に従って、-Oまたは-Iを選択します。

    $ unzip -h
    UnZip 6.00 of 20 April 2009, by Debian. Original by Info-Zip.
      ...
      -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
      -I CHARSET  specify a character encoding for UNIX and other archives
      ...
    

    これは、単に-Oを試してみればうまくいくことを意味します。Unixで.Zipファイルを作成する人はそれほど多くないからです...


だから、あなたの具体的な例については:

  1. 正確なエンコーディング名はGB18030です。

  2. 私は-Oフラグを使用します:

    $ unzip -O GB18030 gb18030.Zip -d target_dir
    Archive:  gb18030.Zip
       creating: target_dir/【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12/
      inflating: target_dir/【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12/【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12.ass
    

    ... できます。

22
mbdevpl

ほとんどのPOSIXファイルシステムでは、ファイル名は単なる一連のバイトであり、意味を理解するのはユーザー空間次第です。これを有利に使用できます。

  1. まず、bsdtarツールがファイル名を壊すように見えるため、unzipを使用してアーカイブを抽出しますが、bsdtarはそれらを生で抽出します。 (私はこれをLinuxでテストしています。FreeBSDは単にtarと呼んでいると思います。)

    $ bsdtar xf gb18030.Zip
    
  2. iconvなどのツールが名前を正常にデコードできることを確認します。

    $ find . | iconv -f gb18030 -t utf-8
    

    (これはfind出力にのみ影響し、ファイル自体には影響しないことに注意してください。)

  3. 最後にconvmvを使用して、ファイル名をUTF-8に変換します。

    $ convmv -r -f gb18030 -t utf-8 --notest .
    

    (注:GB18030をサポートするには、CPANからEncode :: HanExtraをインストールする必要がありましたand手動でuse Encode::HanExtra;を/ usr/bin/convmvに追加します。

  4. convmvが利用できない場合は、スクリプトで記述します。

    $ find . -depth | while read -r old; do
        old=./$old;
        head=${old%/*};
        tail=${old##*/};
        new=$head/$(echo "$tail" | iconv -f gb18030 -t utf-8);
        [ "$old" = "$new" ] || mv "$old" "$new";
    done
    

    (少なくともLinuxでは、これにはiconvがほぼ常に利用可能であり、alwaysがgb18030をサポートするという利点があります。)

11
user1686

方法1:unarユーティリティを使用します

Sudo apt-get install unar

unar -e gb18030 gb18030.Zip

方法2:pythonスクリプトを使用してファイルを解凍します(参照 https:// Gist。 github.com/usunyu/dfc6e56af6e6caab8018bef4c3f3d452#file-gbk-unzip-py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# unzip-gbk.py

import os
import sys
import zipfile
import argparse

parser = argparse.ArgumentParser()
parser.add_argument("--encoding", help="encoding for filename, default gbk")
parser.add_argument("-l", help="list filenames in zipfile, do not unzip", action="store_true")
parser.add_argument("file", help="process file.Zip")
args = parser.parse_args()
print "Processing File " + args.file

file=zipfile.ZipFile(args.file,"r");
if args.encoding:
    print "Encoding " + args.encoding
for name in file.namelist():
    if args.encoding:
        utf8name=name.decode(args.encoding)
    else:
        utf8name=name.decode('gbk')
    pathname = os.path.dirname(utf8name)
    if args.l:
        print "Filename " + utf8name
    else:
        print "Extracting " + utf8name
        if not os.path.exists(pathname) and pathname!= "":
            os.makedirs(pathname)
        data = file.read(name)
        if not os.path.exists(utf8name):
            fo = open(utf8name, "w")
            fo.write(data)
            fo.close
file.close()

例gb18030.Zipは次のファイルを抽出します

【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12
【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12/【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12.ass
11
javacom

OS Xでは、 The Unarchiver と呼ばれるGUIアプリケーションを使用できます。 Mac App Store または Homebrew Cask を使用してインストールできます。

brew cask install the-unarchiver

一緒にZipファイルを開くと、アプリケーションでは、アーカイブからのファイル名のプレビューを使用して適切なエンコーディングを選択できます。

5
Melebius

7zはスイッチ-scsで文字セットIDをサポートします。例:

7z x -scs903 some.Zip

ここで、903は中文簡體文字セットです。文字セットIDのより長いリストが見つかります here

4
ohho

7zを使用してファイルを抽出する

7z x yourfile.Zip

その後、それらのファイル名のエンコーディングを自分で変換します。

convmv --notest -f from_encoding -t utf-8 -r your_extracted_folder/

これは私にとってはうまくいきます。私の場合、from_encodingはtis-620(タイ語のエンコーディングです)であり、あなたはあなたの言語の適切なエンコーディングを見つける必要があります。一般的な方法で通常は問題が解決しますが、ファイル名がまだ判読できない場合は、from_encodingをwindows-1252やshift-jis(日本語)などに変更してみてください。コマンドを使用して、利用可能なエンコーディングを一覧表示できます。

convmv --list
iconv --list

これは私にとって非常にシンプルな「解決方法」の方法です。

1
off99555

7Zipを使用しただけで、適切なエンコーディングを選択できました。

(標準のZipでは実行できなかったもの)

しかし、WindowsではGUIツールを使用して使用しました。コマンドライン7zもうまくいくかもしれません。

0
Berry Tsakala

シェルshiconvを含む1行のスクリプト:

for f in /path/*.txt; do mv $f `echo $f | iconv -f 866 -t UTF-8`; done

上記のスクリプトはループでwhilecardを繰り返し、ファイルを1つのコードページ(866)から別のコードページ(utf8)に移動します。

同じで、パイプラインからwhileカードを読むと:

echo * | for f in `read f&&echo $f`; do mv $f `echo $f | iconv -f 866 -t UTF-8`; done

拒否されたアクセス権がある場合を除いて、出力はありません。また、両方のコードページでファイル名が同じ場合、ファイルを同じパスに移動するように表示されるため、警告が表示される可能性があります。

0
oklas