দুটি ডিরেক্টরি সামগ্রীর তুলনা করা


92

আমার দুটি ডিরেক্টরি রয়েছে যা একই ফাইলগুলি ধারণ করে এবং একই ডিরেক্টরি কাঠামো থাকা উচিত।

আমি মনে করি যে এই ডিরেক্টরিগুলির মধ্যে একটিতে কিছু অনুপস্থিত।

ব্যাশ শেলটি ব্যবহার করে, আমার ডিরেক্টরিগুলির সাথে তুলনা করার এবং তাদের মধ্যে একটির অন্যটিতে উপস্থিত ফাইলগুলি অনুপস্থিত আছে কিনা তা দেখার কোনও উপায় আছে?


1
এর আউটপুট কি bash --version?
জবিন

1
একই কিন্তু আরো নির্দিষ্ট: stackoverflow.com/questions/16787916/...
সিরো Santilli新疆改造中心法轮功六四事件

উত্তর:


63

এই তুলনা করার একটি ভাল উপায় হল এর সাথে ব্যবহার findকরা md5sum, তারপরে ক diff

উদাহরণ

ডিরেক্টরিতে সমস্ত ফাইল তালিকাবদ্ধ করতে অনুসন্ধান ব্যবহার করুন তারপরে প্রতিটি ফাইলের জন্য এমডি 5 হ্যাশ গণনা করুন এবং এটি ফাইলের নাম অনুসারে বাছাই করা একটি পাইপে পাইপ করুন:

find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt

অন্য ডিরেক্টরিতে একই পদ্ধতিটি করুন:

find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt

তারপরে ফলাফল দুটি ফাইলের সাথে তুলনা করুন diff:

diff -u dir1.txt dir2.txt

অথবা প্রক্রিয়া প্রতিস্থাপন ব্যবহার করে একটি একক কমান্ড হিসাবে:

diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)

আপনি যদি কেবল পরিবর্তনগুলি দেখতে চান:

diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")

ডিফের সাথে তুলনা করার জন্য কাট কমান্ড কেবল হ্যাশ (প্রথম ক্ষেত্র) প্রিন্ট করে। অন্যথায় ডিফ প্রতিটি লাইনে মুদ্রণ করবে কারণ হ্যাশ একই থাকলেও ডিরেক্টরি পাথগুলি পৃথক হবে।

তবে আপনি জানেন না কোন ফাইলটি পরিবর্তন হয়েছে ...

তার জন্য, আপনি এর মতো কিছু চেষ্টা করতে পারেন

diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*\// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*\// /')

এই কৌশলটি খুব কার্যকর যখন তুলনা করতে হবে দুটি ডিরেক্টরি একই মেশিনে নেই এবং আপনার উভয় ডিরেক্টরিতে ফাইল সমান কিনা তা নিশ্চিত করতে হবে।

কাজটি করার আরও একটি ভাল উপায় হ'ল গিট-এর diffকমান্ডটি ব্যবহার করা (ফাইলগুলির বিভিন্ন অনুমতি থাকলে সমস্যা হতে পারে -> প্রতিটি ফাইল তখন আউটপুটে তালিকাভুক্ত হয়):

git diff --no-index dir1/ dir2/

1
এটি কোনও অতিরিক্ত বাছাইকরণ পদক্ষেপ ব্যতীত কাজ করে না, কারণ findযে ফাইলগুলিকে তালিকাভুক্ত করা হবে তার ক্রম দুটি ডিরেক্টরিতে পৃথক হবে।
ফাহিম মিঠা

1
ফাইলগুলি বাছাই করতে Askubuntu.com/a/662383/15729 এ বর্ণিত পদ্ধতিটি কেউ ব্যবহার করতে পারেন ।
ফাহিম মিঠা

1
আমি ত্রুটি পেয়েছি `` সন্ধান করুন:
এমডি

1
@ হিউম্যান আপনি কী লিনাক্স ডিস্ট্রো ব্যবহার করছেন তা আমি জানি না তবে সম্ভবত আপনাকে একটি প্যাকেজ ইনস্টল করতে হবে যা ডি এমডি 5সুম সরবরাহ করবে। ফেডোরার 26 এ আপনি এটির সাথে এটি ইনস্টল করতে পারেন: # ডিএনএফ কোর্টিল ইনস্টল করুন
অ্যাডেল জুনিয়র

পরিবর্তে এমডি 5 () ব্যবহার করুন
বুজ

81

আপনি diffকমান্ডটি ঠিক তেমনি ফাইলের জন্য ব্যবহার করতে পারেন:

diff <directory1> <directory2>

আপনি যদি সাবফোল্ডার এবং-ফাইলগুলিও দেখতে চান তবে আপনি -rবিকল্পটি ব্যবহার করতে পারেন :

diff -r <directory1> <directory2>

2
diffডিরেক্টরিগুলির জন্য কাজ করে তাও জানত না (ম্যান ডিফারফাই এটি নিশ্চিত করেছেন) তবে এটি সাব-ডাইরেক্টরির ভিতরে সাব-ডিরেক্টরিতে পরিবর্তনগুলি পুনরুদ্ধার করে পরীক্ষা করে না।
জবিন

1
@ জোবিন এটি অদ্ভুত ... আমার জন্য এটি কাজ করে।
অ্যালেক্স আর।

1
আমার এরকম কিছু রয়েছে: a/b/c/d/a, x/b/c/d/b। আপনি কি diff a xদেয় দেখুন ।
জবিন

2
আপনাকে -rবিকল্পটি ব্যবহার করতে হবে । এটি ( diff -r a x) আমাকে দেয়:Only in a/b/c/d: a. only in x/b/c/d: b.
অ্যালেক্স আর।

3
ডিফ আমাকে পার্থক্যগুলি ফাইলের মধ্যে দেখান তবে কোনও ডিরেক্টরিতে যদি এমন কোনও ফাইল থাকে যা অন্য একটিতে থাকে না !!! আমার ফাইলের মধ্যে পার্থক্যগুলি জানতে হবে না তবে এটি যদি কোনও ডিরেক্টরি কোনও ডিরেক্টরিতে থাকে এবং
অন্যটিতে

24

আপনি ব্যাশ ব্যবহার করছেন না এর মাধ্যমে আপনি --briefএবং এর সাথে আলাদা ব্যবহার করে এটি করতে পারেন --recursive:

$ diff -rq dir1 dir2 
Only in dir2: file2
Only in dir1: file1

man diffউভয় অপশন রয়েছে:

-q, --brief
প্রতিবেদন শুধুমাত্র ফাইল ভিন্ন

-r, --recursive
পুনরাবৃত্তিভাবে পাওয়া যে কোনও উপ-ডিরেক্টরিকে তুলনা করুন


13

এখানে কেবল ফাইলের নামগুলি তুলনা করার জন্য একটি বিকল্প রয়েছে, এবং সেগুলির বিষয়বস্তু নয়:

diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)

এটি নিখোঁজ হওয়া ফাইল তালিকাভুক্ত করার একটি সহজ উপায়, তবে অবশ্যই এটি একই নামযুক্ত ফাইলগুলি নয় তবে বিভিন্ন বিষয়বস্তু সনাক্ত করবে !

(ব্যক্তিগতভাবে আমি আমার নিজস্ব diffdirsস্ক্রিপ্ট ব্যবহার করি তবে এটি বৃহত্তর গ্রন্থাগারের অংশ )


3
আপনি অস্থায়ী ফাইলগুলি না করে প্রক্রিয়া বদলি ব্যবহার করতে চান ...
এমনিআইপি

3
নোট করুন যে এটি কোনও বিশেষ অক্ষরের সাথে ফাইলের নাম সমর্থন করে না, সেক্ষেত্রে আপনি শূন্য-ডিলিমিটারগুলি ব্যবহার করতে চাইতে পারেন যা এএফএআইসি diffএখন পর্যন্ত সমর্থন করছে না। কিন্তু git.savannah.gnu.org/cgit/coreutils.git/commit/…comm যেহেতু এটি সমর্থন করছে তা তাই একবার আপনার কাছের কোর্টিলগুলি এলে আপনি এটি করতে পারেন comm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)(যার আউটপুটটিতে আপনাকে আরও ফর্ম্যাটে রূপান্তর করতে হতে পারে) আপনার --output-delimiterপ্যারামিটার এবং অতিরিক্ত সরঞ্জামগুলি ব্যবহার করতে হবে )।
phk

7

এক বিকল্প হতে পারে দুইবার আরএসসিএন চালানো:

rsync -r -n -t -v -O --progress -c -s /dir1/ /dir2/

পূর্ববর্তী লাইনের সাহায্যে আপনি ফাইলগুলি পাবেন যা dir1 এ রয়েছে এবং dir2 এ আলাদা (বা অনুপস্থিত) রয়েছে।

rsync -r -n -t -v -O --progress -c -s /dir2/ /dir1/

Dir2 জন্য একই

#from the rsync --help :
-r, --recursive             recurse into directories
-n, --dry-run               perform a trial run with no changes made
-t, --times                 preserve modification times
-v, --verbose               increase verbosity
    --progress              show progress during transfer
-c, --checksum              skip based on checksum, not mod-time & size
-s, --protect-args          no space-splitting; only wildcard special-chars
-O, --omit-dir-times        omit directories from --times

আপনি -nপরিবর্তনগুলি সহ্য করতে বিকল্পটি মুছতে পারেন । এটি দ্বিতীয় ফোল্ডারে ফাইলের তালিকাটি অনুলিপি করছে।

আপনি যদি এটি করেন তবে -uনতুন ফাইলগুলি ওভাররাইট করা এড়াতে একটি ভাল বিকল্প হ'ল ।

-u, --update                skip files that are newer on the receiver

একটি এক-লাইনার:

rsync -rtvcsOu -n --progress /dir1/ /dir2/ && rsync -rtvcsOu -n --progress /dir2/ /dir1/

3

আপনি যদি প্রতিটি ফাইলকে প্রসারণযোগ্য এবং সংযোগযোগ্য করতে চান তবে আপনি আউটপুটটি diff -rভিমে পাইপ করতে পারেন ।

প্রথমে ভিমকে ভাঁজ করার নিয়ম দেওয়া যাক:

mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim

এখন কেবল:

diff -r dir1 dir2 | vim -

আপনি মারতে পারেন zoএবং zcখোলা এবং বন্ধ ভাঁজ করা। ভিম থেকে বেরিয়ে আসতে হিট করুন:q<Enter>


3

অজগরটি অর্জন করা মোটামুটি সহজ কাজ:

python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2

DIR1এবং এর জন্য প্রকৃত মান প্রতিস্থাপন করুন DIR2

এখানে নমুনা রান:

$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF

পঠনযোগ্যতার জন্য, এখানে ওয়ান-লাইনারের পরিবর্তে একটি আসল স্ক্রিপ্ট রয়েছে:

#!/usr/bin/env python
import os, sys

d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()

if d1 == d2:
    print("SAME")
else:
    print("DIFF")

2
মনে রাখবেন যে os.listdirকোনও নির্দিষ্ট আদেশ দেয় না। সুতরাং তালিকাগুলিতে বিভিন্ন ক্রমে একই জিনিস থাকতে পারে এবং তুলনাটি ব্যর্থ হবে।
মুড়ু

1
@muru ভাল পয়েন্ট, আমি যে বাছাই অন্তর্ভুক্ত করব
Sergiy Kolodyazhnyy

3

সের্গির জবাবে অনুপ্রাণিত হয়ে আমি দুটি পাইরিওর ডিরেক্টরি তুলনা করার জন্য আমার নিজস্ব পাইথন স্ক্রিপ্ট লিখেছিলাম।

অন্যান্য অনেকগুলি সমাধানের বিপরীতে এটি ফাইলগুলির বিষয়বস্তুর তুলনা করে না। এছাড়াও এটি সাব-ডিরেক্টরিগুলির ভিতরে যায় না যা ডিরেক্টরিগুলির একটিতে অনুপস্থিত। সুতরাং আউটপুট বেশ সংক্ষিপ্ত এবং স্ক্রিপ্ট বড় ডিরেক্টরি সঙ্গে দ্রুত কাজ করে।

#!/usr/bin/env python3

import os, sys

def compare_dirs(d1: "old directory name", d2: "new directory name"):
    def print_local(a, msg):
        print('DIR ' if a[2] else 'FILE', a[1], msg)
    # ensure validity
    for d in [d1,d2]:
        if not os.path.isdir(d):
            raise ValueError("not a directory: " + d)
    # get relative path
    l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
    l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
    # determine type: directory or file?
    l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
    l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
    i1 = i2 = 0
    common_dirs = []
    while i1<len(l1) and i2<len(l2):
        if l1[i1][0] == l2[i2][0]:      # same name
            if l1[i1][2] == l2[i2][2]:  # same type
                if l1[i1][2]:           # remember this folder for recursion
                    common_dirs.append((l1[i1][1], l2[i2][1]))
            else:
                print_local(l1[i1],'type changed')
            i1 += 1
            i2 += 1
        elif l1[i1][0]<l2[i2][0]:
            print_local(l1[i1],'removed')
            i1 += 1
        elif l1[i1][0]>l2[i2][0]:
            print_local(l2[i2],'added')
            i2 += 1
    while i1<len(l1):
        print_local(l1[i1],'removed')
        i1 += 1
    while i2<len(l2):
        print_local(l2[i2],'added')
        i2 += 1
    # compare subfolders recursively
    for sd1,sd2 in common_dirs:
        compare_dirs(sd1, sd2)

if __name__=="__main__":
    compare_dirs(sys.argv[1], sys.argv[2])

যদি আপনি এটি নামের একটি ফাইলে সংরক্ষণ করেন compare_dirs.py, আপনি পাইথন 3.x দিয়ে এটি চালাতে পারেন:

python3 compare_dirs.py dir1 dir2

নমুনা আউটপুট:

user@laptop:~$ python3 compare_dirs.py old/ new/
DIR  old/out/flavor-domino removed
DIR  new/out/flavor-maxim2 added
DIR  old/target/vendor/flavor-domino removed
DIR  new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR  new/tools/tools/LiveSuit_For_Linux64 added

PS যদি আপনার সম্ভাব্য পরিবর্তনের জন্য ফাইলের আকার এবং ফাইল হ্যাশগুলির তুলনা করতে হয় তবে আমি এখানে একটি আপডেট স্ক্রিপ্ট প্রকাশ করেছি: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779


1
ধন্যবাদ, আমি আমার পছন্দ মতো করে তৈরি করতে Gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 এড়িয়ে যেতে / উপেক্ষা করতে একটি alচ্ছিক তৃতীয় প্যারাম রিজেক্সপ যোগ করেছি:cmpdirs dir1 dir2 '/\.git/'
মাইক

0

আমি এই তালিকায় একটি নোডজেস বিকল্প যুক্ত করব যা আমি কিছু সময় আগে লিখেছি।

Dir-তুলনা

npm install dir-compare -g
dircompare dir1 dir2

0

আমি সবেমাত্র আবিষ্কার করেছি এমন একটি দুর্দান্ত সরঞ্জামের পরামর্শ দিতে চাই: মেল্ড

এটি সঠিকভাবে কাজ করে এবং diffলিনাক্স-ভিত্তিক সিস্টেমে কমান্ডটি দিয়ে আপনি যা কিছু করতে পারেন , সেখানে একটি দুর্দান্ত গ্রাফিক ইন্টারফেস দিয়ে প্রতিলিপি তৈরি করা যেতে পারে! উপভোগ করুন

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.