décompresser ZIP avec l'encodage donné


26

J'ai obtenu des fichiers ZIP, qui contiennent des fichiers, dont les noms de fichiers sont dans un certain encodage. Disons que je connais l'encodage de ces noms de fichiers, mais je ne sais toujours pas comment les décompresser correctement.

Voici un exemple de fichier , il contient un fichier "【SSK 字幕 组】 The Vampire Diaries 吸血鬼 日记 S06E12.ass"

Je sais que l'encodage utilisé est GB18030 (chinois)

La question est - comment décompresser ce fichier dans FreeBSD à l'aide de la décompression ou d'un autre utilitaire CLI pour obtenir le nom de fichier encodé approprié? J'ai essayé tout ce que je pouvais, mais le résultat n'a jamais été bon. Veuillez aider.

J'ai essayé sur 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!

J'ai essayé similaire avec décompresser, mais j'ai un problème similaire.

Merci, essayant maintenant sur BSD GRATUIT, où je me connecte en utilisant SSH depuis OSX (Terminal):

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

La première chose, je voudrais est de montrer correctement les noms chinois. j'ai changé

setenv LC_ALL zh_CN.GB18030
setenv LANG zh_CN.GB18030

Ensuite, j'ai téléchargé le fichier et essayez de "ls" pour voir les caractères appropriés, mais pas de chance. Je pense donc que je dois résoudre les premiers paramètres régionaux chinois pour vérifier quand j'obtiens un résultat correct, en fait je peux le comparer. Pouvez-vous aussi m'aider s'il vous plait?

Réponses:


22

Voici ce que je fais sur Ubuntu 16.04 pour décompresser un zip dans n'importe quel encodage, tant que je sais ce qu'est cet encodage. La même méthode devrait fonctionner sur FreeBSD car elle ne repose que sur un unzipoutil largement disponible .

  1. Je revérifie le nom exact de l'encodage, pour ne pas le mal orthographier: https://www.iana.org/assignments/character-sets/character-sets.xhtml

  2. Je cours simplement

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

    ou

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

    choisir entre -Oou -Iselon les instructions ici:

    $ 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
      ...
    

    ce qui signifie que j'essaie simplement -Oet que cela devrait fonctionner, car peu de gens créeraient un .zipfichier sous Unix ...


Donc, pour votre exemple spécifique:

  1. Le nom d'encodage exact est GB18030.

  2. J'utilise le -Odrapeau et:

    $ 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
    

    ... Ça marche.


Pour les zips créés par Greek Windows, j'ai réussi avec cette méthode et le codage CP737
ndemou

Bravo! J'ai revérifié la page de manuel, cela fonctionne mais totalement non documenté, aucun achèvement zsh n'a ce paramètre.
ttimasdf

2
unzipn'a pas cette option dans Mac OS X et crée toujours des noms de fichiers encodés en pourcentage. La unarsuggestion de @ javacom a fonctionné comme un charme.
Phil Krylov

Ressemble à une fonctionnalité spécifique à Debian. Mon unzipdit que c'est UnZip 6.00 of 20 April 2009, by Info-ZIP. Maintained by C. Spieleret ne fournit pas de telles options.
L29Ah

2
@ L29Ah My unzipdans Debian 9 est exactement la même version et n'a pas de telles options. Probablement spécifique à Ubuntu?
Arnie97

11

Sur la plupart des systèmes de fichiers POSIX, le nom de fichier n'est qu'une série d'octets et il appartient à l'espace utilisateur de le comprendre. Vous pouvez utiliser ça à votre avantage.

  1. Tout d'abord, extrayez l'archive en utilisant bsdtar, car l' unzipoutil semble modifier les noms de fichiers, tandis que bsdtar les extraira bruts. (Je teste cela sur Linux. Je suppose que FreeBSD l'appelle simplement tar.)

    $ bsdtar xf gb18030.zip
    
  2. Vérifiez que des outils comme iconvpeuvent décoder les noms avec succès:

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

    (Notez que cela n'affecte que la findsortie, pas les fichiers eux-mêmes.)

  3. Enfin, utilisez convmvpour convertir les noms de fichiers en UTF-8:

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

    (Remarque: j'ai dû installer Encode :: HanExtra à partir du CPAN pour la prise en charge du GB18030 et l' ajouter manuellement use Encode::HanExtra;à / usr / bin / convmv même s'il est censé

  4. En cas d' convmvindisponibilité, scriptez-le:

    $ 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
    

    (Au moins sous Linux, cela présente un avantage car il iconvest presque toujours disponible et prend toujours en charge gb18030.)


merci grawity à ce sujet. Je teste actuellement sur OSX (mais c'est vraiment proche de FreeBSD, et je pense que le résultat sera similaire). ajouter un commentaire à ma question, ne peut pas modifier ici ...
2ge

1
@ 2ge: Ah, OSX pourrait en fait être très différent, car HFS + force en interne les noms de fichiers dans NFD UTF-16 plutôt que de stocker des bytestrings, il est donc possible que cela corrompre les noms GB18030 avant que vous n'ayez la possibilité de les convertir.
user1686

J'ai édité la question d'origine, ajoutez quelques commentaires supplémentaires.
2ge

Oui, je l'ai essayé sur macOS Sierra et bsdtar a signalé de nombreuses erreurs "Impossible de créer xxx" (car les noms du répertoire parent sont corrputés). J'ai dû copier mon archive sur un VPS Linux, utiliser unzip -O pour l'extraire et copier le résultat sur mon Mac en utilisant ssh -C.
Chang Qian, le

10

Méthode 1 : utilisez l'utilitaire Unar

sudo apt-get install unar

unar -e gb18030 gb18030.zip

Méthode 2 : utilisez un script python pour décompresser le fichier (référence 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()

L'exemple gb18030.zip va extraire le fichier suivant

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

2
Merci, la unarméthode est la plus simple au moins sur Mac OS X.
Phil Krylov

4

Sous OS X, vous pouvez utiliser une application GUI appelée The Unarchiver . Il peut être installé à l'aide du Mac App Store ou de Homebrew Cask :

brew cask install the-unarchiver

Lorsque vous ouvrez un fichier ZIP avec celui-ci, l'application vous permet de choisir l'encodage approprié en utilisant l'aperçu d'un nom de fichier à partir de l'archive.


4

7z prend en charge l'ID de jeu de caractères avec un commutateur -scs, par exemple:

7z x -scs903 some.zip

où 903 est le jeu de caractères 中文 簡體. Une liste plus longue des ID de jeux de caractères peut être trouvée ici .


2
7z -scsLe commutateur choisit uniquement l'encodage de la @liste de fichiers définie par.
Phil Krylov

1

Utilisez 7z pour extraire le fichier

7z x yourfile.zip

Après cela, convertissez vous-même l'encodage de ces noms de fichiers:

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

Cela fonctionne pour moi .. from_encoding dans mon cas est tis-620 (qui est un encodage thaï), vous devez trouver un encodage approprié de votre langue. Un populaire résout généralement le problème, mais si le nom du fichier est toujours illisible, essayez de passer de_encoding à d'autres choses telles que windows-1252 ou shift-jis (japonais) ou autre, vous pouvez répertorier l'encodage disponible à l'aide de la commande:

convmv --list
iconv --list

Pour moi, c'est une méthode très simple de "résolution".


0

je viens d'utiliser 7zip et il a réussi à choisir le bon encodage.

(quelque chose que le zip standard ne pouvait pas faire)

mais je l'ai utilisé sous Windows, avec l'outil GUI. Peut-être que la ligne de commande 7z fonctionnera également pour vous.


Il y a une réponse recommandant 7z et votre réponse n'y ajoute rien de plus.
Melebius

1
Oui, il y a maintenant une autre réponse recommandant 7z. Vous pouvez difficilement vous attendre à ce que la réponse de Berry "ajoute plus" à une réponse qui a été publiée près de cinq mois plus tard.
Scott

@Scott Mes excuses, je n'ai pas lu correctement les abréviations du mois anglais.
Melebius

D'ACCORD. Vous voudrez peut-être savoir que, si vous placez le pointeur de votre souris sur une date sur la page (et que vous la "survolez"), il vous montrera la date sous forme de nombres. (Au moins, cela fonctionne sur les ordinateurs; les gens disent que cela ne fonctionne pas bien sur les téléphones.) En outre, en bas à droite de la question, vous verrez «les votes les plus anciens actifs». Il s'agit de l'ordre de tri des réponses. Si vous cliquez sur «le plus ancien», vous obtiendrez les réponses dans l'ordre, du plus ancien au plus récent.
Scott
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.