rozpakuj ZIP z podanym kodowaniem

26

Mam pliki ZIP, które zawierają pliki, których nazwy plików są w pewnym stopniu kodowane. Powiedzmy, że znam kodowanie tych nazw plików, ale nadal nie wiem, jak poprawnie je zdekompresować.

Oto przykładowy plik , który zawiera jeden plik „【SSK 字幕 组】 The Vampire Diaries 吸血鬼 日记 S06E12.ass”

Wiem, że używane kodowanie to GB18030 (chiński)

Pytanie brzmi - jak rozpakować ten plik we FreeBSD za pomocą unzip lub innego narzędzia CLI, aby uzyskać odpowiednią zakodowaną nazwę pliku? Próbowałem wszystkiego, co mogłem, ale wynik nigdy nie był dobry. Proszę pomóż.

Próbowałem na 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!

Próbowałem podobnie z rozpakowaniem, ale mam podobny problem.

Dzięki, teraz próbuję na BEZPŁATNEJ BSD, gdzie łączę się za pomocą SSH z 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

Pierwszą rzeczą, którą chciałbym, to właściwe pokazywanie chińskich nazwisk. Zmieniłem

setenv LC_ALL zh_CN.GB18030
setenv LANG zh_CN.GB18030

Następnie pobrałem plik i spróbowałem napisać „ls”, aby zobaczyć odpowiednie znaki, ale nie powodzenia. Myślę więc, że muszę rozwiązać pierwsze chińskie ustawienia narodowe, aby sprawdzić, kiedy otrzymam właściwy wynik, właściwie mogę go porównać. Czy możesz mi w tym pomóc?

2ge
źródło

Odpowiedzi:

22

Oto, co robię na Ubuntu 16.04, aby rozpakować zip w dowolnym kodowaniu, o ile wiem, co to za kodowanie. Ta sama metoda powinna działać na FreeBSD, ponieważ opiera się tylko na powszechnie dostępnym unzipnarzędziu.

  1. Dokładnie sprawdzam dokładną nazwę kodowania, aby go nie przeliterować: https://www.iana.org/assignments/character-sets/character-sets.xhtml

  2. Po prostu biegnę

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

    lub

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

    wybierając pomiędzy -Olub -Izgodnie z instrukcjami tutaj:

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

    co oznacza, że ​​po prostu próbuję -Oi powinno działać, ponieważ niewiele osób utworzy .zipplik w Uniksie ...


Na przykład:

  1. Dokładna nazwa kodowania to GB18030.

  2. Używam -Oflagi i:

    $ 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
    

    ... to działa.

mbdevpl
źródło
W przypadku zamków błyskawicznych utworzonych przez greckie Windows miałem sukces z tą metodą i kodowaniem CP737
ndemou
Brawo! Dwukrotnie sprawdziłem stronę podręcznika, to faktycznie działa, ale całkowicie nieudokumentowane, żadne zsh zakończenie nie ma tego parametru.
ttimasdf
3
unzipnie ma tej opcji w Mac OS X i zawsze tworzy nazwy plików zakodowane procentowo. Sugestia @ javacom unardziałała jako urok.
Phil Krylov
Wygląda na funkcjonalność specyficzną dla Debiana. Mój unzipmówi, że to UnZip 6.00 of 20 April 2009, by Info-ZIP. Maintained by C. Spieleri nie zapewnia takich opcji.
L29Ah
2
@ L29Ah My unzipin Debian 9 jest dokładnie tą samą wersją i nie ma takich opcji. Prawdopodobnie specyficzny dla Ubuntu?
Arnie97
11

W większości systemów plików POSIX nazwa pliku to tylko seria bajtów i zależy to od przestrzeni użytkownika, aby ją zrozumieć. Możesz to wykorzystać na swoją korzyść.

  1. Najpierw wypakuj archiwum używając bsdtar, ponieważ unzipnarzędzie wydaje się zmieniać nazwy plików, a bsdtar wyodrębni je. (Testuję to w systemie Linux. Wydaje mi się, że FreeBSD po prostu to nazywa tar).

    $ bsdtar xf gb18030.zip
    
  2. Sprawdź, czy narzędzia takie jak iconvmogą z powodzeniem dekodować nazwy:

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

    (Pamiętaj, że wpływa to tylko na dane findwyjściowe, a nie na same pliki).

  3. Na koniec użyj convmvdo konwersji nazw plików na UTF-8:

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

    (Uwaga: musiałem zainstalować Encode :: HanExtra z CPAN do obsługi GB18030 i ręcznie dodać use Encode::HanExtra;do / usr / bin / convmv, nawet jeśli powinien

  4. W przypadku convmvniedostępności, wykonaj skrypt:

    $ 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
    

    (Przynajmniej w systemie Linux ma to tę zaletę, że iconvjest prawie zawsze dostępne i zawsze obsługuje gb18030.)

użytkownik1686
źródło
dzięki grawitacji, patrząc na to. Testuję teraz na OSX (ale to naprawdę bardzo blisko FreeBSD i myślę, że wynik będzie podobny). dodając komentarz na moje pytanie, nie można edytować tutaj ...
2ge
1
@ 2ge: Ach, OSX może być całkiem inny, ponieważ HFS + wewnętrznie wymusza nazwy plików w NFD UTF-16 zamiast przechowywania bajtów, więc istnieje możliwość, że uszkodzi nazwy GB18030, zanim pojawi się szansa na ich konwersję.
user1686,
Zredagowałem oryginalne pytanie, dodaj kilka komentarzy.
2ge
Tak, wypróbowałem to na macOS Sierra i bsdtar zgłosił wiele błędów „Nie udało się utworzyć xxx” (ponieważ nazwy katalogów nadrzędnych są niepoprawne). Musiałem skopiować moje archiwum na system Linux VPS, użyj rozpakować -O, aby je rozpakować, i skopiować wynik z powrotem na komputer Mac, używając ssh -C.
Chang Qian,
10

Metoda 1 : Użyj narzędzia Unar

sudo apt-get install unar

unar -e gb18030 gb18030.zip

Metoda 2 : Użyj skryptu Pythona, aby rozpakować plik (odniesienie 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()

Przykład gb18030.zip rozpakuje następujący plik

【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12
【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12/【SSK字幕组】The Vampire Diaries 吸血鬼日记S06E12.ass
javacom
źródło
2
Dziękuję, ta unarmetoda jest najbardziej bezproblemowa przynajmniej w systemie Mac OS X.
Phil Krylov
4

W systemie OS X można użyć aplikacji GUI o nazwie The Unarchiver . Można go zainstalować za pomocą Mac App Store lub Homebrew Cask :

brew cask install the-unarchiver

Po otwarciu pliku ZIP aplikacja pozwala wybrać odpowiednie kodowanie za pomocą podglądu nazwy pliku z archiwum.

Melebius
źródło
4

7z obsługuje ID zestawu znaków za pomocą przełącznika -scs, np .:

7z x -scs903 some.zip

gdzie 903 to 簡體 簡體 zestaw znaków. Dłuższą listę identyfikatorów zestawów znaków można znaleźć tutaj .

ohho
źródło
2
7z -scsPrzełącznik wybiera tylko kodowanie @listy plików zdefiniowanych.
Phil Krylov
1

Użyj 7z, aby wyodrębnić plik

7z x yourfile.zip

Następnie przekonwertuj kodowanie tych nazw plików:

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

To działa dla mnie .. from_encoding w moim przypadku to tis-620 (co jest kodowaniem tajskim), musisz znaleźć odpowiednie kodowanie swojego języka. Popularny zwykle rozwiązuje problem, ale jeśli nazwa pliku jest nadal nieczytelna, spróbuj zmienić kod z__kodowania na inne rzeczy, takie jak Windows-1252 lub Shift-Jis (japoński) lub cokolwiek innego, możesz wyświetlić dostępne kodowanie za pomocą polecenia:

convmv --list
iconv --list

Jest to dla mnie bardzo prosta metoda „jak rozwiązać”.

off99555
źródło
0

właśnie użyłem 7zip i udało mi się wybrać odpowiednie kodowanie.

(coś, czego nie mógł zrobić standardowy zip)

ale używał go w systemie Windows z narzędziem GUI. Być może wiersz poleceń 7z też będzie dla ciebie działał.

Berry Tsakala
źródło
Jest odpowiedź zalecająca 7z, a twoja odpowiedź nie dodaje do niej nic więcej.
Melebius
1
Tak, jest teraz inna odpowiedź zalecająca 7z. Trudno oczekiwać, że odpowiedź Berry'ego „doda więcej” do odpowiedzi, która została opublikowana prawie pięć miesięcy później.
Scott
@Scott Przepraszam, nie udało mi się poprawnie odczytać skrótów miesiąca angielskiego.
Melebius
DOBRZE. Możesz wiedzieć, że jeśli umieścisz kursor myszy nad dowolną datą na stronie (i „najedziesz na nią”), wyświetli datę w postaci liczb. (Przynajmniej działa to na komputerach; ludzie twierdzą, że nie działa dobrze na telefonach.) Ponadto poniżej prawego dolnego rogu pytania zobaczysz „aktywne najstarsze głosy”. To jest kolejność sortowania odpowiedzi. Jeśli klikniesz „najstarszy”, otrzymasz odpowiedzi w kolejności od najstarszej do najnowszej.
Scott