अगर दो gzipped फाइलें बराबर हैं तो मैं कैसे जांच सकता हूं?


11

मैं केवल एक पाठ फ़ाइल में डेटा डंप करके "गूंगा" बैकअप करते हुए अंतरिक्ष को बचाने की कोशिश कर रहा हूं। मेरी बैकअप स्क्रिप्ट रोज़ निष्पादित होती है और इस तरह दिखाई देती है:

  1. बैकअप दिनांक के नाम से एक निर्देशिका बनाएँ।
  2. टेक्स्ट फ़ाइल में कुछ डेटा डंप करें "$name"
  3. यदि फ़ाइल वैध है, तो इसे gzip करें gzip "$name":। अन्यथा, rm "$name"

अब मैं एक फ़ाइल को निकालने के लिए एक अतिरिक्त कदम जोड़ना चाहता हूं यदि एक ही डेटा पहले दिन में उपलब्ध था (और सिमलिंक या हार्डलिंक बनाने के लिए)।

सबसे पहले मैंने उपयोग करने के बारे में सोचा md5sum "$name", लेकिन यह काम नहीं करता है क्योंकि मैं फ़ाइल नाम और निर्माण तिथि भी संग्रहीत करता हूं।

क्या gzipदो gzipped फ़ाइलों की तुलना करने का विकल्प है और मुझे बताएं कि क्या वे समान हैं या नहीं? यदि gzipऐसा कोई विकल्प नहीं है, तो क्या मेरे लक्ष्य को प्राप्त करने का एक और तरीका है?


1
इसे आज़माएं: linux.die.net/man/1/zdiff
mreithub

2
मैं सुझाव देने जा रहा था diff <(zcat file1) <(zcat file2), लेकिन mrethub का सुझाव zdiffबेहतर लग रहा था।
केविन

backuppc आपके लिए वही करता है जो आप मैन्युअल रूप से हासिल करने की कोशिश कर रहे हैं
drone.ah

@ drohne.ah बैकपेक एक ओवरकिल की तरह हो सकता है अगर यह प्रति दिन सिर्फ एक फ़ाइल है ... (मुझे लगता है कि यह एक SQL डंप की तरह है जहाँ यह बहुत समझ में आता है)
mreithub

1
@ mdpc एमडी 5 में एल्गोरिथ्म की समस्याएं शायद प्रासंगिक नहीं हैं। टकरावों का निर्माण संभव है, लेकिन संभवत: चिंता केवल वही होती है जो संयोगवश होती है, किसी हमलावर द्वारा नहीं। और यह तब भी होने की संभावना नहीं है जब तक आपके पास ~ 2 ^ 64 फाइलें न हों। यहां तक ​​कि प्रिमिज अटैक से भी कोई फर्क नहीं पड़ता।
derobert

जवाबों:


7

आप उपयोग कर सकते हैं zcmpया zdiff(या केविन के आदेश है, जो समान है) mreithub उसकी टिप्पणी में पता चलता है के रूप में। ये अपेक्षाकृत अक्षम होंगे, क्योंकि वे वास्तव में दोनों फ़ाइलों को विघटित करते हैं और फिर उन्हें बंद cmpया पास करते हैं diff। यदि आप बस "वे वही हैं" का जवाब देना चाहते हैं, तो आप चाहते हैं cmp, यह बहुत तेज़ होगा।

के साथ आपका दृष्टिकोण md5sumपूरी तरह से अच्छा है, लेकिन दौड़ने से पहले आपको एमडी 5 लेने की आवश्यकता है gzip। फिर परिणामस्वरूप .gzफ़ाइल के साथ एक फ़ाइल में संग्रहीत करें । आप फ़ाइल को कंप्रेस करने से पहले उसकी तुलना आसानी से कर सकते हैं। यदि नाम समान है, md5sum -cतो यह आपके लिए करेगा।

$ mkdir "backup1"
$ cd backup1
$ echo "test" > backup-file
$ md5sum backup-file > backup-file.md5
$ gzip -9 backup-file

और अगला बैकअप:

$ mkdir "backup2"
$ cd backup2
$ echo "test" > backup-file
$ md5sum -c ../backup1/backup-file.md5 
backup-file: OK

इसलिए यह नहीं बदला है। OTOH, यह बदल गया था:

$ echo "different" > backup-file
$ md5sum -c ../backup1/backup-file.md5 
backup-file: FAILED
md5sum: WARNING: 1 computed checksum did NOT match

यदि आप --quietइसे पास करते हैं, तो यह आपको केवल बाहर निकलने का कोड देगा। मिलान के लिए 0, अंतर के लिए गैर-0।

MD5 काफी तेज है, लेकिन धधकते नहीं हैं। एमडी 4 ( openssl md4कमांड लाइन पर आपको सबसे अच्छा मिलता है, मेरा मानना ​​है) लगभग दो बार तेज है (न तो यह और न ही एमडी 5 सुरक्षित है, लेकिन दोनों टक्कर प्रतिरोधी के रूप में हैं जब कोई भी उन्हें हटाने की कोशिश नहीं कर रहा है)। SHA-1 ( sha1sum) अधिक सुरक्षित है, लेकिन धीमा है; SHA-256 ( sha256sum) सुरक्षित है, लेकिन फिर भी धीमा है। CRC32 कई गुना तेज होना चाहिए, लेकिन कम है और इस तरह अधिक यादृच्छिक टकराव होगा। यह भी पूरी तरह से असुरक्षित है।


zdiffएक बेकार लगता है जैसे मैं सिर्फ यह जानना चाहता हूं कि क्या फ़ाइल बदल गई है, क्या नहीं । zcmpदिलचस्प लग रहा है, मैं कोशिश करूँगा कि।
लेकेन्स्टाइन

7

@derobert का उत्तर बहुत अच्छा है, हालांकि मैं कुछ अन्य जानकारी साझा करना चाहता हूं जो मुझे मिली हैं।

gzip -l -v

gzip- संपीड़ित फ़ाइलों में पहले से ही एक हैश (सुरक्षित नहीं है, हालांकि इस SO पोस्ट को देखें ):

$ echo something > foo
$ gzip foo
$ gzip -v -l foo.gz 
method  crc     date  time           compressed        uncompressed  ratio uncompressed_name
defla 18b1f736 Feb  8 22:34                  34                  10 -20.0% foo

एक सीआरसी को मिला सकते हैं और एक त्वरित फिंगरप्रिंट प्राप्त करने के लिए असम्पीडित आकार को जोड़ सकते हैं:

gzip -v -l foo.gz | awk '{print $2, $7}'

सीएमपी

यह देखने के लिए कि दो बाइट्स समान हैं या नहीं, उपयोग करें cmp file1 file2। अब, एक gzipped फ़ाइल में डेटा और पाद लेख (CRC प्लस मूल आकार) के साथ कुछ हेडर संलग्न हैं। गज़िप प्रारूप का वर्णन बताता है कि हेडर में वह समय होता है जब फ़ाइल को संपीड़ित किया जाता था और यह कि फ़ाइल का नाम एक शून्य-टर्म स्ट्रिंग है जिसे 10-बाइट हेडर के बाद जोड़ा जाता है।

इसलिए, यह मानते हुए कि फ़ाइल नाम स्थिर है और एक ही कमांड ( gzip "$name") का उपयोग किया जाता है, कोई यह जांच सकता है कि क्या cmpसमय सहित पहले बाइट्स का उपयोग करके और छोड़ कर दो फाइलें अलग हैं :

cmp -i 8 file1 file2

नोट : यह धारणा कि समान संपीड़न विकल्प महत्वपूर्ण हैं, अन्यथा कमांड हमेशा फ़ाइल को अलग-अलग रिपोर्ट करेगा। ऐसा इसलिए होता है क्योंकि संपीड़न विकल्प हेडर में संग्रहीत होते हैं और संपीड़ित डेटा को प्रभावित कर सकते हैं। cmpबस कच्चे बाइट्स को देखता है और इसे गज़िप के रूप में व्याख्या नहीं करता है।

यदि आपके पास एक ही लंबाई के फ़ाइल नाम हैं, तो आप फ़ाइल नाम को पढ़ने के बाद बाइट्स की गणना करने की कोशिश कर सकते हैं। जब फ़ाइलनाम अलग-अलग आकार के होते हैं, तो आप cmpबाइट को स्किप करने के बाद चला सकते हैं , जैसे cmp <(cut -b9- file1) <(cut -b10- file2)

zcmp

यह निश्चित रूप से जाने का सबसे अच्छा तरीका है, यह पहले डेटा को संपीड़ित करता है और बाइट्स के साथ तुलना करना शुरू करता है cmp(वास्तव में, यह वही है जो zcmp( zdiff) शेलस्क्रिप्ट में किया गया है )।

एक नोट, मैनुअल पेज में निम्नलिखित नोट से डरो मत:

जब दोनों फ़ाइलों की तुलना करने से पहले असम्पीडित होना चाहिए, दूसरा / tmp के लिए असम्पीडित है। अन्य सभी मामलों में, zdiff और zcmp केवल एक पाइप का उपयोग करते हैं।

जब आपके पास पर्याप्त नया बैश होता है, तो संपीड़न एक अस्थायी फ़ाइल का उपयोग नहीं करेगा, बस एक पाइप। या, जैसा कि zdiffस्रोत कहता है:

# Reject Solaris 8's buggy /bin/bash 2.03.

यदि बाइट 4 (एफएलजी) 0 है, तो फ़ाइल का नाम हेडर में नहीं है, इसलिए आपको इसकी लंबाई के बारे में चिंता करने की आवश्यकता नहीं है। इसके अलावा, मैंने पाया gzip -v -lकि फ़ाइल समय एमटीआईएम के बजाय रिपोर्ट करेगा यदि हेडर में चार एमटीआईएम बाइट शून्य हैं। यह भी ध्यान दें कि यदि MTIME है, तो यह आमतौर पर फ़ाइल समय से पहले थोड़ा सा होता है क्योंकि यह तब होता है जब संपीड़न शुरू हुआ।
किचिन

0

दो गज़िप फ़ाइलों की तुलना करने के लिए, बस सामग्री, एक कमांड, नहीं diff, बस तुलनाmd5sum

$ diff -q <(zcat one.gz|md5sum|cut -f1 -d' ') \
          <(zcat two.gz|md5sum|cut -f1 -d' ') \
    && echo same || echo not_same

आप प्रासंगिक मतभेदों के लिए "फ़िल्टर" भी कर सकते हैं,

$ diff -q <(zcat one.gz|grep -v '^-- Dump completed'|md5sum|cut -f1 -d' ') \
          <(zcat two.gz|grep -v '^-- Dump completed'|md5sum|cut -f1 -d' ') \
   && echo same || echo not_same

यदि स्क्रिप्टिंग है, तो मैं एक फ़िल्टर फ़ंक्शन (परीक्षण नहीं, सिर्फ एक उदाहरण) की सलाह दूंगा,

do_filter_sum() {
  zcat $1 | grep -v '^-- Dump completed' | md5sum | cut -f1 -d' '
}

diff -q <(do_filter_sum one.gz) \
        <(do_filter_sum two.gz) \
        && echo same || echo not_same

Md5sum एक बेकार है, आप उपयोग कर सकते हैं cmpzcatऔर grepमर्ज किया जा सकता है zgrep
लेकेनस्टाइन

सच है, md5sum की तुलना करना आवश्यक नहीं है (जब तक कि आप पहले से ही उन्हें उत्पन्न न करें); मैंने इसका इस्तेमाल तब से किया जब से derobert ने इसका इस्तेमाल किया। zgrep सिर्फ एक स्क्रिप्ट है जो मूल रूप से गनज़िप और grep (या जैसा भी मामला हो सकता है) करता है, इसलिए वहाँ थोड़ा अंतर होता है। स्क्रिप्ट के रूप में पोस्ट जानबूझकर प्लगेबल भागों के साथ पाइप की एक श्रृंखला के रूप में दिखाया गया है; सब कुछ एक ही आदेश में विलय करने में क्या मजा है?
माइकेल

1
और zcatबस है gunzip -c। सही काम के लिए सही उपकरण का उपयोग करें, KISS ब्लोट से बेहतर है। इस मामले में मैं अपना समय कुछ ऐसा लिखने में खर्च करूँगा जो आवश्यकतानुसार कठिन लिंक उत्पन्न करे, यह अधिक मजेदार है।
लेकेनस्टाइन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.