निर्देशिकाओं की तुलना करें लेकिन फाइलों की सामग्री की नहीं


21

Diff -r के साथ मैं यह कार्य कर सकता हूं, हालाँकि इसमें इतना समय लगता है क्योंकि फ़ाइल की सामग्री को अलग करता है।

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

क्या कोई और तरीका है?

जवाबों:


20

rsync, डिफ़ॉल्ट रूप से, केवल फ़ाइल मेटाडेटा की तुलना करता है।

rsync -n -a -i --delete source/ target/

स्पष्टीकरण:

  • -n वास्तव में कॉपी या डिलीट न करें - यह महत्वपूर्ण है !! १
  • -a टाइमस्टैम्प और विशेषताओं जैसी फ़ाइल के सभी मेटाडेटा की तुलना करें
  • -i प्रति फ़ाइल जानकारी की एक पंक्ति प्रिंट करें
  • --delete उन फ़ाइलों की भी रिपोर्ट करें, जो स्रोत में नहीं हैं

नोट: निर्देशिका नामों को स्लैश के साथ जोड़ना महत्वपूर्ण है। यह एक rsync बात है।

यदि आप ऐसी फ़ाइलों के लिए मुद्रित लाइनें भी देखना चाहते हैं जो समान हैं तो -iदो बार प्रदान करें

rsync -n -a -ii --delete source/ target/

उदाहरण आउटपुट:

*deleting   removedfile   (file in target but not in source)
.d..t...... ./            (directory with different timestamp)
>f.st...... modifiedfile  (file with different size and timestamp)
>f+++++++++ newfile       (file in source but not in target)
.f          samefile      (file that has same metadata. only with -ii)

याद रखें कि rsync केवल मेटाडेटा की तुलना करता है। इसका मतलब है कि यदि फ़ाइल सामग्री बदल गई है, लेकिन मेटाडेटा वही रहा है, तो rsync रिपोर्ट करेगा कि फ़ाइल समान है। यह एक असंभावित परिदृश्य है। इसलिए या तो भरोसा करें कि जब मेटाडेटा समान है तो डेटा समान है, या आपको फ़ाइल डेटा की तुलना बिट द्वारा करनी होगी।

बोनस: प्रगति की जानकारी के लिए यहाँ देखें: rsync को पूरा करने के लिए अनुमानित समय या कार्य शेष है?


1
में स्लैश source/और target/दोनों भी बहुत महत्वपूर्ण हैं! (उनके बिना, आप स्रोत और लक्ष्य निर्देशिका नामों की तुलना बाल फ़ाइल नामों के साथ करेंगे, इसलिए सभी फ़ाइल नाम अलग-अलग होंगे।)
peschü

काश मैंने आपकी टिप्पणी पहले पढ़ी होती, यह बहुत महत्वपूर्ण है! मैंने केवल स्रोत में स्लैश को छोड़ दिया और फिर मैं सोच रहा था कि लक्ष्य में फाइलें क्यों नहीं दिखाई दीं *deleting, लेकिन फाइलें, जो स्रोत में हैं केवल दिखाई नहीं दीं। स्लैश को गलती से भूल जाना आसान है और फिर आपको एक प्रशंसनीय लेकिन गलत आउटपुट मिलता है।
user643011

3

-q( --brief) विकल्प के साथ diff -r( diff -qr) का उपयोग करें । infoGNU के लिए पेज से diff:

1.6 जो फ़ाइलों को अलग अलग करना

जब आप केवल यह पता लगाना चाहते हैं कि क्या फाइलें अलग हैं, और आपको परवाह नहीं है कि अंतर क्या हैं, तो आप सारांश आउटपुट प्रारूप का उपयोग कर सकते हैं। इस प्रारूप में, फ़ाइलों के बीच के अंतर को दिखाने के बजाय, diff' simply reports whether files differ. The--brief '(`-q') विकल्प इस आउटपुट स्वरूप का चयन करता है।

दो निर्देशिकाओं की सामग्री की तुलना करते समय यह प्रारूप विशेष रूप से उपयोगी है। यह लाइन तुलनाओं द्वारा सामान्य रेखा को करने की तुलना में बहुत तेज है, क्योंकि `डिफरेंशियल’ फाइलों का विश्लेषण करना बंद कर सकता है क्योंकि यह जानता है कि कोई मतभेद हैं।

यह लाइन द्वारा लाइन की तुलना नहीं करेगा, बल्कि एक पूरे के रूप में फाइल करेगा, जो प्रोसेसर को बहुत तेज करता है (आप जिस चीज की तलाश कर रहे हैं)।


1
- क्यू की समस्या यह है कि यह सामान्य तुलना करता है और जब अंतर पाता है (यदि सामान्य मोड इसकी तुलना करता रहता है तो) बंद हो जाता है, इसलिए यदि विशाल फाइलें समान हैं तो यह बहुत अधिक समय तक चलेगा।
eez0

2

यहाँ एक त्वरित अजगर स्क्रिप्ट है जो यह जाँच करेगी कि फ़ाइल नाम, mtimes और फ़ाइल आकार सभी समान हैं:

import os
import sys

def getStats(path):
    for pathname, dirnames, filenames in os.walk(path):
        for filename in ( os.path.join(pathname, x) for x in filenames ):
            stat = os.stat(filename)
            yield filename[len(path):], stat.st_mtime, stat.st_size

sys.exit(tuple(getStats(sys.argv[1])) != tuple(getStats(sys.argv[2])))

1

यदि आपको केवल यह जानना है कि क्या दो फाइल सिस्टम ब्रांच की फाइलें अलग-अलग हैं (बिना फाइलों के अंदर देखें) आप ऐसा कुछ कर सकते हैं:

find /opt/branch1 -type f | sort | xargs -i md5sum {} >/tmp/branch1;
find /opt/branch2 -type f | sort | xargs -i md5sum {} >/tmp/branch2;
diff /tmp/branch1 /tmp/branch2;

HTH


0

क्रिस डाउन की स्क्रिप्ट के आधार पर, यह स्क्रिप्ट थोड़ी अधिक "दृश्य" है। इसे दो तर्कों के साथ folder1और folder2, यह पहला फ़ोल्डर चलता है और प्रत्येक फ़ाइल के लिए दूसरे फ़ोल्डर में एक संबंधित फ़ाइल खोजता है। यदि यह पाया जाता है, तो सापेक्ष पथ हरे रंग में मुद्रित होता है, यदि उनके पास अलग-अलग संशोधित समय या आकार होता है, तो यह पीले रंग में मुद्रित होता है, और यदि यह नहीं पाया जाता है, तो यह लाल रंग में मुद्रित होता है।

#!/usr/bin/env python

import os
import sys
from termcolor import colored

def compare_filestats(file1,file2):
    """
    Compares modified time and size between two files.
    Return:
        -1 if file1 or file2 does not exist
         0 if they exist and compare equal
         1 if they have different modified time, but same size
         2 if they have different size, but same modified time
         3 if they have different size, and different modified time
    """

    if not os.path.exists(file1) or not os.path.exists(file2):
        return -1

    stat1 = os.stat(file1)
    stat2 = os.stat(file2)

    return (stat1.st_mtime != stat2.st_mtime) \
        + 2*(stat1.st_size != stat2.st_size)

def compare_folders(folder1,folder2):
    """
    folder1: serves as reference and will be walked through
    folder2: serves as target and will be querried for each file in folder1

    Prints colored status for each file in folder1:
        missing: file was not found in folder2 
        mtime  : modified time is different
        size   : filesize is different
        ok     : found with same filestats
    """
    for dirpath, dirnames, filenames in os.walk(folder1):
        for file1 in ( os.path.join(dirpath, x) for x in filenames ):
            relpath = file1[len(folder1):]
            file2 = os.path.join( folder2, relpath )
            comp = compare_filestats(file1,file2)

            if comp < 0:
                status = colored('[missing]','red')
            elif comp == 1:
                status = colored('[mtime  ]','yellow')
            elif comp >= 2:
                status = colored('[size   ]','yellow')
            else:
                status = colored('[ok     ]','green')

            print status, relpath

if __name__ == '__main__':
    compare_folders(sys.argv[1],sys.argv[2])

ध्यान दें कि यह तय करने के लिए पर्याप्त नहीं है कि दोनों फ़ोल्डर समान हैं, आपको यह सुनिश्चित करने के लिए दोनों तरीकों से चलाने की आवश्यकता होगी। व्यवहार में यदि आप यह जानना चाहते हैं कि क्या फ़ोल्डर्स समान हैं , तो क्रिस की स्क्रिप्ट बेहतर है। यदि आप जानना चाहते हैं कि क्या गायब है या एक फ़ोल्डर से दूसरे में अलग है , तो मेरी स्क्रिप्ट आपको बताएगी।

नोट: यदि आप, स्थापित termcolor की आवश्यकता होगी pip install termcolor


0

यदि आप केवल संरचना और फ़ाइलों के बारे में कुछ बुनियादी जानकारी की तुलना करना चाहते हैं, तो आप कुछ इस तरह की कोशिश कर सकते हैं:

diff <(cd $DIR1 && ls -laR) <(cd $DIR2 && ls -laR)

मैंने इसका परीक्षण नहीं किया, इसलिए किसी भी संपादन का स्वागत है :)


2
यह काम नहीं करेगा क्योंकि निर्देशिका नाम स्वयं भी परिणामों में होंगे।
क्रिस डाउन

क्या होगा अगर हम निर्देशिका नामों के साथ पहले कॉलम को बाहर करेंगे? जैसे <(ls -laR | awk '{$ 1 = ""; प्रिंट}')
Volodymyr

सभी लाइनें निर्देशिका नाम नहीं हैं, इसलिए यह ठीक से काम नहीं करेगा।
क्रिस डाउन

इस तथ्य का लाभ उठाएं कि प्रत्येक <()का अपना वातावरण है। संपादित।
बजे एक CVn
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.