Linux: निर्देशिका संरचना की तुलना बिना फाइल्स के करें


54

वास्तव में फाइलों में डेटा की तुलना किए बिना दो निर्देशिका संरचनाओं की तुलना करने का सबसे अच्छा और सरल तरीका क्या है? यह ठीक काम करता है:

diff -qr dir1 dir2_

लेकिन यह वास्तव में धीमा है क्योंकि यह फाइलों की तुलना भी कर रहा है। क्या ऐसा करने के लिए अंतर या किसी अन्य साधारण सीएलआई उपकरण के लिए स्विच है?


"निर्देशिका संरचना" से, क्या आपका मतलब सिर्फ निर्देशिका पथ, या निर्देशिका और गैर-निर्देशिका फ़ाइलों दोनों के पथ हैं?
intuited

हाँ, फ़ोल्डर और फ़ाइलें।
जोनाह

1
उस स्थिति में आपको -type d@ slartibartfast के उत्तर से विकल्प को हटा देना चाहिए या मेरे उत्तर की जांच कर लेनी चाहिए ।
intuited

जवाबों:


36

निम्नलिखित (यदि आप डायरेक्टरी 1 के लिए पहली डायरेक्टरी और डायरेक्टरी 2 के लिए दूसरा विकल्प देते हैं) तो वही करना चाहिए जो आप देख रहे हैं और तेजी से कर रहे हैं:

find directory1 -type d -printf "%P\n" | sort > file1
find directory2 -type d -printf "%P\n" | sort | diff - file1

मूल सिद्धांत यह है कि यह सभी निर्देशिकाओं को प्रिंट करता है जिसमें आधार डायरेक्ट्रीएन निर्देशिका के सापेक्ष उपनिर्देशिका पथ शामिल हैं।

यह नीचे गिर सकता है (उत्पादन में गिरावट) यदि आपके पास कुछ निर्देशिका नामों में कैर्री रिटर्न है, लेकिन अन्य नहीं।


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

जैसा कि इंगित किया गया है (वर्षों पहले), ओप्स प्रश्न का उत्तर देने के लिए, the -ype d को हटाया जाना चाहिए ताकि फाइलों की तुलना में और साथ ही निर्देशिकाओं पर विचार किया जाए
user2746401

मैं समस्या कथन के उस वाचन को समझता और सम्मान करता हूं। उस समय मेरा पढ़ना नहीं था। क्या आप अनुशंसा कर रहे हैं कि मैं अद्यतन किए गए प्रश्न का उत्तर देने के लिए अपना उत्तर संपादित करूं? मैं ठीक कर रहा हूं कि अगर आपको लगता है कि यह कुछ लोगों के लिए मददगार होगा, और मैं ठीक हूं कि समाधान छोड़ दें और टिप्पणी करें जिस तरह से वे अब हैं, जो उचित रूप से प्रभावी लगता है।
Slartibartfast

34
vimdiff <(cd dir1; find . | sort) <(cd dir2; find . | sort)

मुड़े हुए किसी भी सामान्य खंड के साथ आपको दो निर्देशिका पदानुक्रमों का एक अच्छा साइड-बाय-साइड डिस्प्ले देगा।


यह समाधान बेतरतीब ढंग से विफल हो जाता है। जब विम अस्थायी फाइल डिस्क्रिप्टर को पढ़ता है (या फिर से पढ़ता है), तो यह पहले से ही चला गया है।
डेनिलसन सा माया

23

मैं आमतौर पर rsyncइस कार्य के लिए उपयोग करता हूं :

rsync -nav --delete DIR1/ DIR2

हमेशा-n, उर्फ--dry-run, विकल्प काउपयोग करने के लिए सावधान रहें, या यह निर्देशिकाओं की सामग्री को बदल देगा (सामग्री को बदल देगा)।

यह फ़ाइल संशोधन समय और आकार के आधार पर फ़ाइलों की तुलना करेगा ... मुझे लगता है कि आप वास्तव में क्या चाहते हैं, या कम से कम आपको कोई आपत्ति नहीं है अगर ऐसा होता है? मुझे समझ में आया कि आप चाहते हैं कि यह तेज़ी से हो , न कि आपको फ़ाइल सामग्री के बीच के अंतर को अनदेखा करने की आवश्यकता हो। यदि आप चाहते हैं कि यह समान नामों के साथ अलग-अलग फ़ाइलों को सूचीबद्ध न करें, तो मुझे लगता --ignore-existingहै कि विकल्प का जोड़ ऐसा करेगा।

यह भी जान लें कि /अंत में नहीं डालने से DIR1यह निर्देशिका DIR1 की सामग्री के साथ तुलना करने का कारण होगा DIR2

आउटपुट थोड़ा वर्बोज़ होने से समाप्त होता है, लेकिन यह आपको दिखाएगा कि कौन सी फाइलें / निर्देशिका अलग-अलग हैं। फ़ाइलें / निर्देशिका में मौजूद DIR2हैं और इनमें नहीं DIR1शब्द के साथ आरंभ हो जाएगा deleting

कुछ स्थितियों के लिए, @ slartibartfast का उत्तर अधिक उपयुक्त हो सकता है, हालांकि आपको -type dगैर-निर्देशिका फ़ाइलों की सूची को सक्षम करने के लिए विकल्प को हटाने की आवश्यकता होगी । rsyncयदि आप तुलना करने के लिए फ़ाइलों / निर्देशिकाओं की एक महत्वपूर्ण संख्या प्राप्त कर चुके हैं तो और तेज़ हो जाएगा।


बहुत बढ़िया जवाब। Rsync के आउटपुट में deleting...पाठ को नोटिस करना कठिन है, लेकिन यह शायद गति को बनाए रखते हुए फाइलों की तुलना करने के बेहतर तरीकों में से एक है। जब फ़ाइलों को अलग करने की आवश्यकता नहीं होती है, तो यहां अन्य उत्तर तेजी से होते हैं ... ओपी के उदाहरण में, लेकिन मुझे वास्तव में यह पसंद है।
जोएल मेलन

यह वही है जो मैं था। मेरे पास निर्देशिका पेड़ों की एक विशाल जोड़ी में विभिन्न आकारों के साथ कुछ फाइलें थीं, और मैं जानना चाहता था कि कौन से हैं। इसने उस लक्ष्य को मात्र सेकंड में हासिल कर लिया।
सुपरजामी

शायद यह एक उपयोगकर्ता के साथ इसे चलाने के लिए एक अच्छा विचार है, जिसमें केवल पढ़ने के लिए एक्सेस है। जैसा sudo -u nobody rsync -nav --delete d1 d2बशर्ते कि 'दूसरों के लिए झंडे पढ़ने अनुमति देते हैं।
user1182474

इस सॉल्यूशन को चलाते समय मुझे "बिल्डिंग फाइल लिस्ट मिली ... किया \ n भेजा गया एक्स बाइट्स मिला Y बाइट्स Z बाइट्स / सेक टोटल साइज़ है ए स्पीडअप बी" (जहाँ मैंने XYZAB को नंबर के लिए प्रतिस्थापित किया है)। क्या इसका मतलब यह है कि सब कुछ समान था? चूँकि इसमें कुछ अधिक विशिष्ट का उल्लेख नहीं था? अग्रिम धन्यवाद
स्कॉट एच

अपने स्वयं के प्रश्न का उत्तर देने के लिए, मैंने प्रत्येक में अलग-अलग फ़ाइलों को जोड़ने का प्रयोग किया, और ऐसा प्रतीत होता है कि आउटपुट में उल्लिखित कोई भी विशिष्ट फाइल / डायर का अर्थ नहीं है कि वे सभी समान हैं।
स्कॉट एच

18

Ls उत्तर के समान लेकिन यदि आप पेड़ लगाते हैं तो आप कर सकते हैं

tree dir1 > out1
tree dir2 > out2
diff out1 out2

7
या tmpfiles से बचने के लिए,diff <( tree dir1 ) <( tree dir2 )
जोएल मेलन

1
मैं iध्वज के साथ पेड़ चलाने की सलाह देता हूं , जो पेड़ की पंक्तियों ( tree -i dir1, आदि) को प्रिंट नहीं करता है । यदि निर्देशिका संरचना एक स्थान पर भिन्न है, तो अन्य फ़ाइलें जो मेल खाती हैं, उनमें |ट्री आउटपुट में अधिक या कम प्रतीक हो सकते हैं , और फ़ाइल पथ समान होने पर भी उन पंक्तियों को अलग कर देगा।
पूछवचन

2
diff <(tree -i dir1) <(tree -i dir2) अब तक का सबसे अच्छा जवाब है। मुझे उन सभी उत्तरों को नीचा दिखाने का प्रलोभन दिया गया है जो सुझाव देते हैं कि अंतर या rsync स्पष्ट है क्योंकि प्रश्न स्पष्ट रूप से फ़ाइल सामग्री को पढ़ने के लिए नहीं कहता है। नोट: दो पाइपों के उपयोग के सुझाव को कोष्ठक के बीच रिक्त स्थान के सावधानीपूर्वक उपयोग की आवश्यकता है, उदाहरण के लिए सटीक रूप से पालन करें। उदाहरण के लिए दो 20G संस्करणों की तुलना करने के लिए बैकअप के बाद पेड़ के उत्तर में लगभग 5 सेकंड लगते हैं। अन्य को 20+ मिनट लगे।
जेसन मॉर्गन

3

मैं बस इस समस्या का हल ढूंढ रहा था। समाधान जो मुझे सबसे ज्यादा पसंद आया वह था:

comm <(ls DIR1) <(ls DIR2)

यह आपको 3 कॉलम देता है: 1 - केवल डीआईआर 1 में फाइलें, 2 - केवल डीआईआर 2 में फाइलें, 3 - डीआईआर 3 में केवल फाइलें अधिक जानकारी के लिए इस ब्लॉग पोस्ट को देखें।


DIR3निर्दिष्ट कहाँ है ? सब मैं देख रहा है DIR1और DIR2
माइकल डोरस्ट

केवल में सभी फाइलों: मैं इसे करने की कोशिश की, और (मैं क्या बता सकता से) उत्पादन था DIR1में स्तंभ 1 , केवल में सभी फ़ाइलों DIR2में स्तंभ 2 , और सभी फ़ाइलों को दोनों द्वारा साझा में कॉलम 3 । यह उपयोगी है, लेकिन क्या आप जानते हैं कि कोई कॉलम 3 को कैसे छीन सकता है और केवल मतभेदों को छोड़ सकता है? मेरे पास सॉर्ट करने के लिए बहुत सारी फाइलें हैं, और इसमें से ज्यादातर समान हैं। मुझे यह देखने की ज़रूरत नहीं है कि वही क्या है।
माइकल डोरस्ट

1
इसके अलावा, मैंने पाया कि comm <(ls DIR1) <(ls DIR2)पुनरावृत्ति से काम नहीं किया। उसके लिए मैंने इस्तेमाल किया comm <(ls -R1 DIR1) <(ls -R1 DIR2)ls -Rपुनरावर्ती निर्देशिकाओं के माध्यम से क्रॉल करता है, और ls -1ध्यान दें कि यह एक है , न कि एक एल ) lsप्रति पंक्ति केवल एक फ़ाइल नाम प्रिंट बनाता है ।
माइकल डोरस्ट

@ मिचेल: comm -3(देखें man comm)।
ज़ाज

2
ls > dir1.txt

ls > dir2.txt

फिर बस दो सूचियों को अलग करें।


ऐसा लगता है जैसे ओपी पथों का एक उत्तराधिकार चाहता है। यह वर्तमान निर्देशिका में सभी फ़ाइलों को अलग करेगा। यह बहस का मुद्दा है, लेकिन संभव है, वह सिर्फ निर्देशिका चाहता है; वह फ़ाइलों की सामग्री के बजाय फ़ाइल नाम चाहता हो सकता है।
intuited

@intuited - आप सही कह रहे हैं। मैंने इसे गलत बताया।
एमडीएमरा

2

यह इष्टतम समाधान है

diff --brief -r dir1 dir2

-ब्रीप स्विच केवल रिपोर्ट करता है कि क्या फाइलें भिन्न हैं, अंतर का विवरण नहीं।


1
ओपी के पास पहले से ही -qसवाल है, जो के लिए एक उपनाम है --brief। यह उत्तर कोई नई जानकारी प्रदान नहीं करता है।
माइकल डोरस्ट

1
OP फ़ाइल सामग्री की तुलना नहीं करना चाहता है। But it's really slow because it's comparing files too.
जोएल मेलन

1

विभिन्न फ़ाइलों को प्राप्त करने के लिए "diff -qr" का उपयोग करें और फिर फ़ाइल को grep के साथ तुलना करने के लिए फ़िल्टर करें ताकि केवल उन फ़ाइलनामों को प्राप्त कर सकें जो केवल एक निर्देशिका में हैं।

diff -qr dir1 dir2 | grep -v "Files.*differ" 

-3

मुझे लगता है कि केवल rsync उपयोगकर्ता-योग्य है। क्यों?

फ़ाइल और निर्देशिकाओं को रखने के लिए संरचना केवल उपयोगी है। जब हम सीमलिंक का उपयोग करते हैं तो डिफ को पर्याप्त निकास कोड नहीं देते हैं। उस स्थिति में, 2 एक्जिट कोड वापस आ सकते हैं, भले ही src और dst समान हों (समय, आकार, नाम, टाइमस्टैम्प, सॉफ्टलिंक आदि इंगित करते हुए)।

dir, फ़ाइल सिस्टम फ़ाइल ऑर्डरिंग की गारंटी नहीं देता है, भले ही src और dst पर निर्देशिका सामग्री समान हो। हो सकता है कि आपको ls आउटपुट को छाँटकर छानना चाहिए। लेकिन शुद्ध एलएस केवल नोड नामों को प्रदर्शित करता है।

हो सकता है कि स्क्रिप्ट, नोड प्रकारों के लिए diff, cmp, test -X सहित उपयोगी हो, लेकिन कई परीक्षण / cmp रन द्वारा किए गए अधिभार के बारे में याद रखें। स्क्रिप्ट बहुत धीमी होगी।

हमेशा की तरह, यदि आप चाहते हैं कि सरल जानकारी "dirs is / not समान है", तो आपको rsync का उपयोग the -n (dry) विकल्प के साथ करना चाहिए। यदि आप खोजना चाहते हैं कि क्या अलग है, तो अलग कमांड का उपयोग करें।


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