मैं लिनक्स में zip / tgz कैसे बना सकता हूं जैसे कि विंडोज में उचित फ़ाइल नाम हैं?


26

वर्तमान में, tar -zcf arch.tgz files/*UTF में फ़ाइल नाम एन्कोड करता है, इसलिए Windows उपयोगकर्ता उन सभी वर्णों को फ़ाइल नाम में खराब कर देता है जो अंग्रेजी नहीं हैं , और इसके साथ कुछ भी नहीं कर सकते हैं।

zip -qq -r arch.zip files/* एक ही व्यवहार है।

मैं एक ज़िप / tgz संग्रह कैसे बना सकता हूं, जब विंडोज उपयोगकर्ता इसे निकालते हैं, तो सभी फ़ाइल नाम ठीक से एन्कोडेड होंगे?

जवाबों:


24

वर्तमान में, टार ने UTF में फ़ाइलनाम को एनकोड किया

वास्तव में टार फिल्म्स को पूरी तरह से एनकोड / डीकोड नहीं करता है, यह बस उन्हें फाइलसिस्टम से बाहर की तरह कॉपी करता है। यदि आपका स्थान UTF-8-आधारित है (जैसा कि कई आधुनिक लिनक्स डिस्ट्रोस में है), तो वह UTF-8 होगा। दुर्भाग्य से विंडोज बॉक्स का सिस्टम कोडपेज कभी भी यूटीएफ -8 नहीं होता है, इसलिए विनरार जैसे टूल को छोड़कर नामों को हमेशा मंगवाया जाएगा जो कि चार्जसेट को बदलने की अनुमति देते हैं।

इसलिए गैर-एएससीआई फाइलनाम के साथ एक ज़िप फ़ाइल बनाना असंभव है जो विभिन्न देशों के विंडोज के रिलीज और उनके अंतर्निहित संपीड़ित फ़ोल्डर समर्थन पर काम करता है।

यह टार और जिप प्रारूपों की कमी है कि कोई निश्चित या आपूर्ति की गई एन्कोडिंग जानकारी नहीं है, इसलिए गैर-एएससीआईआई अक्षर हमेशा गैर-पोर्टेबल होंगे। यदि आपको गैर-ASCII संग्रह प्रारूप की आवश्यकता है, तो आपको हाल ही में 7z या rar जैसे नए स्वरूपों में से एक का उपयोग करना होगा। दुर्भाग्य से ये अभी भी जीत रहे हैं; 7zip में आपको -mcuस्विच की आवश्यकता है , और rar अभी भी UTF-8 का उपयोग नहीं करेगा, जब तक कि वह कोडपेज में वर्णों का पता नहीं लगाता।

मूल रूप से यह एक भयानक गड़बड़ी है और यदि आप गैर-एएससीआईआई पात्रों के साथ फ़ाइल नाम वाले अभिलेखागार को वितरित करने से बच सकते हैं तो आप बहुत बेहतर होंगे।


बहुत धन्यवाद! दुर्भाग्य से, अधिकांश उपयोगकर्ताओं को 7z के बारे में कुछ नहीं पता है, और rar मालिकाना है :(
kolypto

हाँ, यह एक समस्या है। ज़िप उपयोगकर्ताओं के लिए अब तक सबसे उपयोगी समाधान है, क्योंकि सभी आधुनिक ओएस में इसके लिए अच्छा देशी UI समर्थन है। दुर्भाग्य से charset समस्या वास्तव में आज ज़िप में हल नहीं है (और यहां तक ​​कि अन्य संग्रह स्वरूपों में भी यह अभी भी परेशानी है)।
बॉबीस

25

यहाँ एक साधारण पायथन लिपि है जो मैंने यूनिक्स से टार फाइलों को विंडोज पर अनपैक करने के लिए लिखी है:

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()

बहुत बढ़िया! इस स्क्रिप्ट ने मुझे EUC-JP एन्कोडेड टार फाइल को बदलने में मदद की, जो एक पुराने Solaris सर्वर पर बनाई गई थी।
wm_eddie

सर, आपने मेरी जान बचाई। भगवान आपका भला करे :)
user1576772

8

लिनक्स में डिफॉल्ट tar(GNU टार) का उपयोग करके समस्या को हल किया जाता है ... --format=posixफ़ाइल बनाते समय पैरामीटर को जोड़ा जाता है ।

उदाहरण के लिए:
tar --format=posix -cf

विंडोज़ में, फ़ाइलों को निकालने के लिए, मैं bsdtar का उपयोग करता हूं

में https://lists.gnu.org/archive/html/bug-tar/2005-02/msg00018.html लिखा है (के बाद से 2005 !!):

> मैंने चेंजलॉग में UTF-8 के समर्थन में कुछ पढ़ा। इसका क्या
मतलब है >
> मुझे
अलग-अलग स्थानों के बीच एक संग्रह बनाने का कोई तरीका नहीं मिला जो विनिमेय होगा >।

POSIX.1-2001 प्रारूप (tar --format = posix or --format = pax) में अभिलेखागार बनाते समय, टार फ़ाइल नामों को वर्तमान स्थानों से UTF-8 में परिवर्तित करती है और फिर संग्रह में संग्रहीत करती है। निकालने पर, रिवर्स ऑपरेशन किया जाता है।

PS टाइप करने के बजाय --format=posixआप टाइप कर सकते हैं -H pax, जो छोटा है।


5

मेरा मानना ​​है कि आप जिप कंटेनर प्रारूप के साथ ही समस्याओं में चल रहे हैं। टार उसी समस्या से पीड़ित हो सकता है।

का प्रयोग करें 7zip ( .7z) या RAR ( .rar) पुरालेख फ़ॉर्मेट बजाय। दोनों विंडोज और लिनक्स के लिए उपलब्ध हैं; p7zipसॉफ्टवेयर दोनों स्वरूपों संभालती है।

मैं तो बस बना कर परीक्षण किया .7z, .rar, .zip, और .tarदोनों WinXP और डेबियन 5, और पर फ़ाइलों .7zऔर .rarफ़ाइलों की दुकान / फ़ाइल नाम सही ढंग से बहाल करते हुए .zipऔर .tarफ़ाइलें नहीं है। इससे कोई फर्क नहीं पड़ता कि परीक्षण संग्रह बनाने के लिए किस सिस्टम का उपयोग किया जाता है।


5

मुझे विंडोज उपयोगकर्ताओं से अनपैकिंग tarऔर zipफाइलें मिलने की समस्या थी । हालांकि मैं इस सवाल का जवाब नहीं देता कि "संग्रह कैसे बनाएंगे जो काम करेगा", मूल स्क्रिप्ट की परवाह किए बिना नीचे दी गई स्क्रिप्ट सही ढंग से अनपैक tarऔर zipफ़ाइलों की मदद करती हैं ।

चेतावनी: एक ट्यून करने के लिए स्रोत मैन्युअल एन्कोडिंग (है cp1251, cp866नीचे दिए गए उदाहरण में)। भविष्य में कमांडलाइन विकल्प एक अच्छा समाधान हो सकता है।

टार:

#!/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()

ज़िप:

#!/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 : मैं chardetडेटा के कच्चे चंक की सही एन्कोडिंग का अनुमान लगाने के लिए पैकेज का उपयोग करता हूं । अब स्क्रिप्ट मेरे सभी बुरे अभिलेखागार पर और साथ ही साथ एक अच्छे बॉक्स से बाहर काम करती है।

ध्यान देने योग्य बातें:

  1. सभी फ़ाइलनाम निकाले जाते हैं और एन्कोडिंग अनुमान लगाने वाले इंजन के लिए पाठ का एक बड़ा टुकड़ा बनाने के लिए एकल स्ट्रिंग में विलय कर दिया जाता है। इसका मतलब है कि कुछ फ़ाइलनामों को एक अलग तरीके से खराब कर दिया गया है, प्रत्येक अनुमान को खराब कर सकता है।
  2. एक अच्छा यूनिकोड पाठ ( chardetसामान्य यूनिकोड ऑब्जेक्ट के साथ काम नहीं करता है) को संभालने के लिए विशेष फास्ट-पथ का उपयोग किया गया था ।
  3. परीक्षण करने के लिए सिद्धांतों को जोड़ा जाता है और यह प्रदर्शित करने के लिए कि सामान्यक किसी भी छोटे आवेश पर किसी भी एन्कोडिंग को पहचानता है।

अंतिम संस्करण:

#!/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."

आपके कार्यक्रमों के लिए धन्यवाद! खेद, ज़िप कार्यक्रम अजगर 3 के तहत काम नहीं करता है, लेकिन यह अजगर 2. तहत काम करता है
beroal

@beroal, मैंने स्क्रिप्ट को अपडेट किया। अब यह फ़ायरफ़ॉक्स के लिए मोज़िला द्वारा एन्कोडिंग को ऑटोडेक्ट करने के लिए विकसित इंजन का उपयोग करता है।
dmitry_romanov

4

POSIX-1.2001 निर्दिष्ट करता है कि TAR UTF-8 का उपयोग कैसे करता है।

2007 तक, PKZIP APPNOTE.TXT ( http://www.pkware.com/documents/casestudies/APPNOTE.TXT ) में चेंगलॉग संस्करण 6.3.0 निर्दिष्ट करता है कि ज़िप UTF-8 का उपयोग कैसे करता है।

यह केवल वह उपकरण है जो इन मानकों का ठीक से समर्थन करता है, यह एक खुला प्रश्न है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.