Linux'ta Windows uygun dosya adlarına sahip olacak şekilde nasıl zip / tgz oluşturabilirim?


26

Şimdilik, tar -zcf arch.tgz files/*UTF'deki dosya adlarını kodlar, bu nedenle Windows kullanıcıları dosya adlarında ingilizce olmayan ve onlarla hiçbir şey yapamayan tüm karakterleri görürler .

zip -qq -r arch.zip files/* aynı davranışa sahip.

Nasıl bir zip / tgz arşivi oluşturabilirim ki Windows kullanıcıları çıkardığında tüm dosya isimleri uygun şekilde kodlanacak mı?

Yanıtlar:


24

Şu anda, tar UTF içindeki dosya adlarını kodluyor

Aslında tar, dosya adlarını hiç kodlamaz / kodunu çözmez, Olduğu gibi dosya sisteminden kopyalar. Yerel ayarınız UTF-8 tabanlıysa (birçok modern Linux dağıtımında olduğu gibi), bu UTF-8 olur. Ne yazık ki, bir Windows kutusunun sistem kod sayfası hiçbir zaman UTF-8 değildir, bu nedenle kullanılan karakter kümesinin değiştirilmesine izin veren WinRAR gibi araçlar haricinde adlar her zaman karıştırılır.

Bu nedenle, farklı ülkelerin Windows sürümlerinde ve yerleşik sıkıştırılmış klasör desteğinde çalışan ASCII olmayan dosya adlarıyla bir ZIP dosyası oluşturmak mümkün değildir.

Sabit ve verilen bir kodlama bilgisi bulunmadığından tar ve zip formatlarından bir eksiklik olduğu için ASCII olmayan karakterler her zaman taşınabilir olmayacaktır. ASCII olmayan bir arşiv biçimine ihtiyacınız varsa, en son 7z veya rar gibi daha yeni biçimlerden birini kullanmanız gerekir. Ne yazık ki bunlar hala riskli; 7zip dosyasında -mcuanahtara ihtiyacınız vardır ve kod dosyası, kod sayfasında olmayan karakterleri tespit etmediği sürece UTF-8 kullanmayacaktır.

Temelde korkunç bir karışıklık ve ASCII olmayan karakterlerle dosya isimlerini içeren arşivleri dağıtmaktan kaçınmanız durumunda, çok daha iyi durumda olacaksınız.


Çok teşekkürler! Ne yazık ki, çoğu kullanıcı 7z hakkında hiçbir şey bilmez ve rar tescillidir :(
kolypto

Evet, bu bir problem. ZIP, tüm modern işletim sistemlerinde yerel kullanıcı arayüzü desteğinin iyi olması nedeniyle kullanıcılar için en kullanışlı çözümdür. Maalesef karakter kümesi sorunu bugün ZIP’de çözülemiyor (ve hatta diğer arşiv formatlarında bile sorunlu).
bobince

25

İşte Windows'ta UNIX'ten tar dosyalarını açmak için yazdığım basit bir Python betiği:

import tarfile

archive_name = "archive_name.tar"

def recover(name):
    return unicode(name, 'utf-8')

tar = tarfile.open(name=archive_name, mode='r', bufsize=16*1024)
updated = []
for m in tar.getmembers():
    m.name = recover(m.name)
    updated.append(m)

tar.extractall(members=updated)
tar.close()

Müthiş! bu komut dosyası, eski bir Solaris sunucusunda oluşturulan EUC-JP kodlu tar dosyasını dönüştürmeme yardımcı oldu.
wm_eddie

Efendim, hayatımı kurtardınız. Tanrı sizi korusun :)
user1576772 5:15

8

Linux'ta varsayılan tar(GNU tar) kullanan sorun, --format=posixdosya oluşturulurken parametre eklenerek çözüldü .

Örneğin:
tar --format=posix -cf

Windows'ta dosyaları ayıklamak için bsdtar kullanıyorum .

In https://lists.gnu.org/archive/html/bug-tar/2005-02/msg00018.html o (beri yazılır 2005 !!):

> ChangeLog'da UTF-8'in desteklenmesi hakkında bir şeyler okudum. Bu ne anlama
geliyor?
>
Farklı yerler arasında değiştirilebilir bir arşiv oluşturmanın bir yolunu bulamadım .

POSIX.1-2001 formatında (tar --format = posix veya --format = pax) arşiv oluştururken, tar dosya isimlerini geçerli yerel ayarlardan UTF-8'e dönüştürür ve sonra bunları arşivde saklar. Çıkarırken, ters işlem gerçekleştirilir.

PS Yazmak yerine , daha kısa olan --format=posixyazabilirsiniz -H pax.


5

Zip konteynır formatının kendisiyle ilgili sorunlar yaşadığına inanıyorum. Tar aynı problemden muzdarip olabilir.

Kullanım 7zip ( .7z) ya da RAR ( .rar) arşiv formatlarını yerine. Her ikisi de Windows ve Linux için kullanılabilir; p7zipYazılım her iki biçimi de işler.

Sadece oluştururken test .7z, .rar, .zipve .tarWinXP ve Debian 5, ve her iki dosyalar .7zve .rarederken dosyaları deposunda / doğru dosya adları geri .zipve .tardosyalar yok. Test arşivini oluşturmak için hangi sistemin kullanıldığı önemli değildir.


5

Paket açma tarve zipWindows kullanıcılarından aldığım dosyalar ile ilgili sorunlar yaşadım. "Çalışacak olan arşivin nasıl oluşturulacağı" sorusuna cevap vermeme rağmen , asıl işletim sisteminden bağımsız olarak aşağıdaki komut dosyaları doğru şekilde açılmaya tarve zipdosyaları açmaya yardımcı olur .

UYARI: Bir ayarlamak için (kaynak el kodlayan sahiptir cp1251, cp866aşağıdaki örneklerde). Komut satırı seçenekleri gelecekte iyi bir çözüm olabilir.

Katran:

#!/usr/bin/env python

import tarfile
import codecs
import sys

def recover(name):
    return codecs.decode(name, 'cp1251')

for tar_filename in sys.argv[1:]:
    tar = tarfile.open(name=tar_filename, mode='r', bufsize=16*1024)
    updated = []
    for m in tar.getmembers():
        m.name = recover(m.name)
        updated.append(m)
    tar.extractall(members=updated)
    tar.close()

zip:

#!/usr/bin/env python

import zipfile
import os
import codecs
import sys

def recover(name):
    return codecs.decode(name, 'cp866')

for filename in sys.argv[1:]:
    archive = zipfile.ZipFile(filename, 'r')
    infolist = archive.infolist()
    for i in infolist:
        f = recover(i.filename)
        print f
        if f.endswith("/"):
            os.makedirs(os.path.dirname(f))
        else:
            open(f, 'w').write(archive.read(i))
    archive.close()

UPD 2018-01-02 : chardetHam veri yığınının doğru kodlandığını tahmin etmek için paketi kullanıyorum . Şimdi senaryo, tüm kötü arşivlerimin yanı sıra, iyi olanların üstünde kutudan çıkıyor.

Dikkat edilecek şeyler:

  1. Kodlama tahmin motoru için metnin daha büyük bir parçasını yapmak üzere tüm dosya adları tek bir dizgeye eklenir ve birleştirilir. Bu, her biri farklı şekilde vidalanan az sayıda dosya adının, tahminde bozulmaya neden olabileceği anlamına gelir.
  2. İyi bir unicode metni işlemek için özel hızlı yol kullanıldı ( chardetnormal bir unicode nesnesiyle çalışmıyor).
  3. Teste eklenir ve normalleştiricinin oldukça kısa bir dizgideki kodlamaları tanıdığını göstermek için eklenir.

Son sürüm:

#!/usr/bin/env python2
# coding=utf-8

import zipfile
import os
import codecs
import sys

import chardet


def make_encoding_normalizer(txt):
    u'''
    Takes raw data and returns function to normalize encoding of the data.
        * `txt` is either unicode or raw bytes;
        * `chardet` library is used to guess the correct encoding.

    >>> n_unicode = make_encoding_normalizer(u"Привет!")
    >>> print n_unicode(u"День добрый")
    День добрый

    >>> n_cp1251 = make_encoding_normalizer(u"Привет!".encode('cp1251'))
    >>> print n_cp1251(u"День добрый".encode('cp1251'))
    День добрый
    >>> type(n_cp1251(u"День добрый".encode('cp1251')))
    <type 'unicode'>
    '''
    if isinstance(txt, unicode):
        return lambda text: text

    enc = chardet.detect(txt)['encoding']
    return lambda file_name: codecs.decode(file_name, enc)


for filename in sys.argv[1:]:
    archive = zipfile.ZipFile(filename, 'r')
    infolist = archive.infolist()

    probe_txt = "\n".join(i.filename for i in infolist)
    normalizer = make_encoding_normalizer(probe_txt)

    for i in infolist:
        print i.filename
        f = normalizer(i.filename)
        print f
        dirname = os.path.dirname(f)
        if dirname:
            assert os.path.abspath(dirname).startswith(os.path.abspath(".")), \
                "Security violation"
            if not os.path.exists(dirname):
                os.makedirs(dirname)
        if not f.endswith("/"):
            open(f, 'w').write(archive.read(i))
    archive.close()


if __name__ == '__main__' and len(sys.argv) == 1:
    # Hack for Python 2.x to support unicode source files as doctest sources.
    reload(sys)
    sys.setdefaultencoding("UTF-8")

    import doctest
    doctest.testmod()

    print "If there are no messages above, the script passes all tests."

Programlarınız için teşekkürler! Maalesef, Zip programı Python 3 altında çalışmıyor, ancak Python 2 altında çalışıyor.
beroal

@ beroal, betiği güncelledim. Artık kodlamayı otomatik olarak belirlemek için Firefox için Mozilla tarafından geliştirilen motoru kullanıyor.
dmitry_romanov

4

POSIX-1.2001, TAR'nin UTF-8'i nasıl kullandığını belirtti.

2007'den itibaren, PKZIP APPNOTE.TXT'deki ( http://www.pkware.com/documents/casestudies/APPNOTE.TXT ) 6.3.0 sürümünün changelog sürümü ZIP'in UTF-8'i nasıl kullandığını belirtti.

Bu standartları yalnızca hangi araçların doğru bir şekilde desteklediğinin açık bir sorusu var.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.