अतिरिक्त डिस्क स्थान का उपयोग किए बिना, मैं लिनक्स पर एक फ़ाइल को कैसे संपीड़ित कर सकता हूं?


20

मुझे 100GB ड्राइव मिली है जिसमें 95GB फ़ाइल है। मुझे ड्राइव पर कुछ स्थान खाली करने की आवश्यकता है (और अभी ड्राइव से फाइल स्थानांतरित करना एक विकल्प नहीं है)। फ़ाइल अच्छी तरह से gzipया bz2जो भी हो, के साथ संपीड़ित होगी , लेकिन ये सभी प्रोग्राम संपीड़ित फ़ाइल को एक अलग फ़ाइल में लिखते हैं। मेरे पास इसके लिए पर्याप्त खाली जगह नहीं है।

क्या किसी भी अतिरिक्त डिस्क स्थान (या कम से कम न्यूनतम अतिरिक्त डिस्क स्थान) का उपयोग किए बिना फ़ाइल को संपीड़ित करने के लिए मानक संपीड़न उपकरण या अन्य यूनिक्स उपयोगिताओं का उपयोग करने का एक तरीका है? मैं एक ऐसी चीज़ का चित्रण कर रहा हूँ जो एक बार में फ़ाइल के हिस्से को संपीड़ित करती है और सीधे फाइल पर परिणाम लिखती है। मुझे लगता है कि यह जोखिम भरा होगा, क्योंकि संपीड़न बाधित होने पर फ़ाइल दूषित हो जाएगी, लेकिन मुझे नहीं लगता कि मेरे पास कोई विकल्प है।


एक अंतिम विकल्प जो हम अपने पुराने स्थान पर उपयोग करते थे, वह था कहीं एक डायर, जिसमें कचरे से भरी 1G फाइलों का एक पूरा गुच्छा था। फिर, यदि आप एक चुटकी में मिल गए, तो आप उनमें से कुछ को हटा सकते हैं ताकि आपको थोड़ी जगह मिल सके।

जवाबों:


13

यह अवधारणा को एक-लाइनर को बैश करने का प्रमाण है, लेकिन यह आपको शुरू करना चाहिए। अपने जोखिम पार इस्तेमाल करें।

truncate -s `gzip -c file | dd of=file conv=notrunc 2>&1 | sed -n '$ s/ .*$// p'` file
mv file file.gz

यह gz डेटा को एक dd प्रक्रिया में पाइप करके काम करता है जो इसे उसी फ़ाइल पर वापस लिखता है। पूरा होने पर, फ़ाइल को gz आउटपुट के आकार में काट दिया जाता है।

यह मानता है कि dd के आउटपुट की अंतिम पंक्ति मेल खाती है:

4307 बाइट्स (4.3 kB) कॉपी किया गया, 2.5855e-05 s, 167 MB / s

जहां पहला क्षेत्र बाइट्स का पूर्णांक लिखा गया है। यह वह आकार है जिसके लिए फ़ाइल को छोटा करना होगा। मुझे 100% यकीन नहीं है कि आउटपुट प्रारूप हमेशा समान होता है।


निफ्टी की चाल क्या आप बता सकते हैं कि क्यों conv=notruncजरूरी है?
१५

शायद यह नहीं है। gzip -c file | dd of=fileबस के रूप में अच्छी तरह से काम करने के लिए प्रकट होता है।
user710307

1
जुड़े हुए प्रश्न पर लोगों ने इसे आज़माया (और मैंने इसे भी आज़माया); यह सामान्य रूप से काम नहीं करता है। लगता है कि यह केवल बहुत छोटी फ़ाइलों के लिए काम करता है - शायद क्योंकि gzip एक छोटी फाइल को RAM में कंप्रेस करने से पहले पढ़ लेगा। बड़ी फ़ाइलों (कुछ एमबी) के लिए, यह काम नहीं करता है, भले ही वे संकुचित हों।
१५

3
हां। तो कनव = notrunc आवश्यक है।
user710307

1
क्या यह संभव नहीं है कि किसी भी समय संपीड़न प्रोग्राम (जैसे gzip) मूल डेटा बाइट्स की तुलना में अधिक हेडर और डेटा बाइट्स लिखता है, इस प्रकार फ़ाइल के कुछ हिस्सों को अधिलेखित कर देता है? मुझे लगता है कि यह चुने हुए संपीड़न कार्यक्रम पर निर्भर करता है। क्या किसी को यह पता है कि ऐसा होने से कैसे रोका जाए या कैसे (im) संभावित है?
डेनियल बॉमर

7

यह इतना नहीं है कि gzipऔर bzip2मूल के ऊपर लिख। बल्कि, वे संकुचित डेटा को एक नई फ़ाइल के रूप में डिस्क पर लिखते हैं, और यदि वह ऑपरेशन सफल होता है, तो वे मूल असम्पीडित फ़ाइल को अनलिंक करते हैं।

यदि आपके पास पर्याप्त रैम है, तो आप फ़ाइलों को एक tmpfsफ़ाइल सिस्टम में अस्थायी रूप से संपीड़ित करने के लिए एक स्क्रिप्ट लिख सकते हैं , फिर डिस्क पर मूल को हटा दें और इसे संपीड़ित संस्करण से बदल दें। शायद कुछ इस तरह:

# some distributions mount /dev/shm as tmpfs; replace with bzip2 if you prefer
if gzip -q9c /full/disk/somefile > /dev/shm/somefile.gz
then
    rm -f /full/disk/somefile && mv -i /dev/shm/somefile.gz /full/disk
fi

बस अपने मेमोरी उपयोग के प्रति सावधान रहें, क्योंकि tmpfsअनिवार्य रूप से एक रैम डिस्क है। एक बड़ी आउटपुट फ़ाइल सिस्टम को आसानी से भुना सकती है और आपके लिए अन्य समस्याओं का कारण बन सकती है।


1
वह काम करने के लिए बस पागल है
एंड्रयू लैम्बर्ट

मुझे लिफाफा पुश करना पसंद है।
जेम्स स्नेनरिंग

3

कोई उपकरण नहीं है जो इस तरह से काम करता है, ठीक उसी कारण से जो आप देते हैं। कुछ लोग एक उपकरण लिखने के लिए तैयार हैं जो जानबूझकर जोखिम भरा व्यवहार लागू करता है।


मैं उम्मीद कर रहा था कि यह उपयोगिता के लिए एक असुरक्षित, गैर-डिफ़ॉल्ट विकल्प होगा। क्या आप कोई विकल्प सोच सकते थे? वहाँ एक जगह में एक फ़ाइल को छोटा करने का एक तरीका है, उदाहरण के लिए पहले 2 जीबी को हटा दें? मुझे एक बार में एक चंक को संपीड़ित करने के लिए मेरे सीमित खाली स्थान का उपयोग करने देगा, स्रोत फ़ाइल को सिकोड़ते हुए जैसे मैं गया था।
ली

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

2
लेकिन आप फ़ाइल के अंत से डेटा निकाल सकते हैं । यह सिद्धांत रूप में किया जा सकता है। आप अलग-अलग फ़ाइलों में डालने के लिए फ़ाइल के अंत से डेटा को स्लाइस करते हैं, जैसे ही आप जाते हैं मूल फ़ाइलों को काटते हुए। फिर आप फ़ॉर्म्स को आगे बढ़ते हुए डिप्रेस करते हैं, जैसे ही आप जाते हैं, उन्हें डिलीट कर देते हैं। यह लागू करने के लिए एक दर्द होगा और अगर कुछ भी गलत हुआ तो आप खराब हो जाएंगे। लेकिन यह संभव है।
डेविड श्वार्ट्ज

1

विभाजन और csplit कमांड का उपयोग बड़ी फाइल को छोटे भागों में विभाजित करने के लिए किया जा सकता है, और फिर उन्हें अलग-अलग संपीड़ित किया जा सकता है। फिर से दौड़ना हालांकि समय लेने वाला होगा।


एक और अच्छा विकल्प। ऐसा करने के लिए कोई स्क्रिप्ट लिख सकता है। हालाँकि, यह कई अलग-अलग संपीड़ित फ़ाइलों की पैदावार करता है, जिन्हें पुन: व्यवस्थित करने के बाद फिर से मिलाना होगा, जो इतना अच्छा नहीं है।
१५
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.