একটি ডিরেক্টরিতে বিদ্যমান ফাইলগুলি সন্ধান করুন তবে অন্যটিতে [বন্ধ] নেই


295

আমি একটি ডিরেক্টরিতে বিদ্যমান ফাইলগুলি সন্ধান করার চেষ্টা করছি তবে অন্যটিতে নেই, আমি এই আদেশটি ব্যবহার করার চেষ্টা করেছি:

diff -q dir1 dir2

উপরোক্ত কমান্ডের এটি উভয় ফাইল খুঁজে বের করে দিয়ে সমস্যা dir1কিন্তু না dir2ভাল ফাইল হিসেবে হিসেবে dir2কিন্তু না dir1,

আমি ফাইল খুঁজে বের করার চেষ্টা করছি dir1কিন্তু নেই dir2শুধুমাত্র।

আমার ডেটা কেমন লাগে তার একটি ছোট নমুনা এখানে

dir1    dir2    dir3
1.txt   1.txt   1.txt
2.txt   3.txt   3.txt
5.txt   4.txt   5.txt
6.txt   7.txt   8.txt

আমার মনে আরও একটি প্রশ্ন হ'ল আমি কীভাবে ফাইলগুলিকে সন্ধান করতে পারি dir1তবে একটি কমান্ডের মধ্যে dir2বা dir3একক কমান্ডে নয়?

উত্তর:


390
diff -r dir1 dir2 | grep dir1 | awk '{print $4}' > difference1.txt

ব্যাখ্যা:

  • diff -r dir1 dir2 ফাইলগুলি কেবল ডিআর 1 এ রয়েছে এবং কেবলমাত্র ডিআর 2 এ রয়েছে এবং উভয় ডিরেক্টরিতে উপস্থিত ফাইলগুলির পরিবর্তনগুলি যদি দেখায় তবে তা দেখায়।

  • diff -r dir1 dir2 | grep dir1 কোন ফাইলগুলি কেবল dir1 এ রয়েছে তা দেখায়

  • awk শুধুমাত্র ফাইলের নাম মুদ্রণ করতে।


5
আমি নিশ্চিত হতে grepচাই ^dir1যে dir1এই পথে আমি আর হাজির হব না ।
আলফে

@ আলফ এটি উন্নত করা যেতে পারে। আমি $4উদাহরণ হিসাবে ব্যবহার করি । প্রকৃতপক্ষে, আমার প্রকৃত উবুন্টুতে, ইতালীয় diffজবাব দেয়। $4ইতালিয়ান এবং ইংরেজী জবাবগুলির জন্য ঠিক আছে তবে আমি অন্য সকল ভাষার পক্ষে নিশ্চিত নই ...
অ্যাসপ্লেপিক্স

139

এটি কাজ করা উচিত:

diff -rq dir1 dir2

বিকল্পগুলি ব্যাখ্যা করা হয়েছে (ডিফ (1) ম্যান পৃষ্ঠার মাধ্যমে ):

  • -r - পুনরাবৃত্তভাবে পাওয়া যে কোনও উপ-ডিরেক্টরিকে তুলনা করুন।
  • -q - কেবলমাত্র ফাইলগুলি পৃথক কিনা আউটপুট।

8
নিস! তবে আমি মনে করি এটি এর মতো বাড়ানো উচিত:diff -rq dir1 dir2 | grep 'Only in dir1/'
sobi3ch

2
এটি সামগ্রী দ্বারা তুলনা করা হয়, তবে ধীর ড্রাইভগুলিতে দীর্ঘ সময় নিতে পারে।
স্মিটারলিঙ্ক

5
-qবিকল্পটিতে কেবল একটি নোট : ম্যান পৃষ্ঠাগুলি কেবল "ফাইলগুলি পৃথক করে কিনা কেবল আউটপুট" বলে, এটি পৃথক কিনা তা পরীক্ষা করে না। আমি উত্স কোডটি অনুধাবন করে আবিষ্কার করেছি যে এটি কেবলমাত্র ফাইলের আকারগুলি পার্থক্য নির্ধারণের জন্য পরীক্ষা করে, প্রকৃত সামগ্রী নয়।
ryancdotnet

-qবিকল্পটি সম্পর্কে আমি পুনরুত্পাদন করতে পারি না যে এটি কেবল ফাইলের আকার পরীক্ষা করে। জিএনইউ ডিফুটিলেটস ৩.7 ব্যবহার করে একই ফাইল আকারের সাথে দুটি ফাইলের তুলনা করে তবে diff -q file1 file2ফলাফলগুলি আউটপুটগুলির সাথে আলাদা হয় Files file1 and file2 differ
স্টিফান শ্মিড্ট

50
comm -23 <(ls dir1 |sort) <(ls dir2|sort)

এই কমান্ডটি আপনাকে ডিআর 1-তে নয় এমন ফাইলগুলি দেবে যা ডায়ার 2-এ নয়

<( )সাইন সম্পর্কে , আপনি এটি 'প্রক্রিয়া প্রতিস্থাপন' হিসাবে গুগল করতে পারেন।


উপ-ডিরেক্টরিতেও কাজ করা ভাল হবে, আমি মনে করি (ls -R dir1|sort)কৌশলটি করতে পারব
উলকাস

1
এটি ওএস এক্স পুনরুদ্ধার মোডে কাজ করবে।
অ্যান্টনি ভ্যানোভার

@ulkas, আপনি যদি ব্যবহার করেন তবে আউটপুটটি ভুল হতে পারে (ls -R dir|sort)
অ্যান্ড্রি মাকুখা

3
রঙিন হাইলাইটিংয়ের সাথে ভিমডিফ অনেক সুন্দর ভিজ্যুয়াল তুলনা সরবরাহ করে:vimdiff <(ls dir1 |sort) <(ls dir2|sort)
লোগান রিড

32

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

উদাহরণ:

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

find /dir1/ -type f -exec md5sum {} \; > dir1.txt

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

find /dir2/ -type f -exec md5sum {} \; > dir2.txt

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

diff dir1.txt dir2.txt

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

কাজটি করার আরও একটি ভাল উপায় হ'ল গিট

git diff --no-index dir1/ dir2/

শুভেচ্ছান্তে!


1
আমি গিটে গেলাম না গিট রেপোর অভ্যন্তরে যে স্বেচ্ছাসেবী ডিরেক্টরি রয়েছে সেগুলিতে আলাদা করতে পারি ... দুর্দান্ত !!! এই উত্তরটি আমার জন্য কেবল একটি বড় সমস্যা সমাধান করেছে, আপনাকে ধন্যবাদ
ভিক্টরনোভা

17

ক্ষেত্রের ( http://meldmerge.org/ ) ডিরেক্টরি এবং এর মধ্যে থাকা ফাইলগুলির সাথে তুলনা করার ক্ষেত্রে দুর্দান্ত কাজ করে।

মাউন্ট ডিরেক্টরি তুলনা



1
লাইন শেষের সাথে কখনও সমস্যা হয়নি। আপনি বিস্তারিত বলতে পারেন?
ক্যাটালিন হিট্কু

হ্যাঁ, এটি লাইন শেষটি নির্দেশ করে না । এর ফলে (বারবার) বিকাশকারীরা এই সরঞ্জামটি ব্যবহার করে সিআরএলএফএলএফ-তে সিআরএলএফএফ তৈরি করে লাইন শেষের "স্থির" করে এমন পরিবর্তন করে যা এই সরঞ্জামটি ব্যবহার করে।
0xC0000022L

3
এটি ফাইলের বিষয়বস্তু পড়ার পক্ষেও জোর দেয় এবং তাই >> 1GB ডিরেক্টরিতে এটি প্রায় অকেজো।
টমিস্লাভ নাকিক-আলফায়ারভিক

13

ডিরেক্টরিগুলির সাথে তুলনা করার জন্য ভিআইএম- এর ডিডিডিফ প্লাগইন হল আরও একটি দরকারী সরঞ্জাম।

vim -c "DirDiff dir1 dir2"

এটি কেবল ডিরেক্টরিগুলির মধ্যে কোন ফাইলগুলি পৃথক করে তা তালিকাভুক্ত করে না, তবে আপনাকে ভিমডিফের সাথে পৃথক পৃথক ফাইলগুলি পরিদর্শন / সংশোধন করার অনুমতি দেয়।


11

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

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

#!/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])

নমুনা ব্যবহার:

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

অথবা আপনি যদি প্রথম ডিরেক্টরি থেকে কেবল ফাইলগুলি দেখতে চান:

user@laptop:~$ python3 compare_dirs.py dir2/ dir1/ | grep dir1
DIR  dir1/out/flavor-domino added
DIR  dir1/target/vendor/flavor-domino added
FILE dir1/tmp/.kconfig-flavor_domino added

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


সরল পর্যাপ্ত স্ক্রিপ্ট যা আমি যা চেয়েছিলাম ঠিক ঠিক তা করে: আমার কাছ থেকে একটি বাল্ক কপি যাচাই করুন: +1 (যদিও পাইথন 2 তে রূপান্তর করার জন্য প্রয়োজন) ইঙ্গিত: সেট ব্যবহারের ফলে পার্থক্যটি আরও সহজ হতে পারে।
জেসন মরগান

6

আরেকটি (সম্ভবত বৃহত্তর ডিরেক্টরিগুলির জন্য দ্রুত) পদ্ধতির:

$ find dir1 | sed 's,^[^/]*/,,' | sort > dir1.txt && find dir2 | sed 's,^[^/]*/,,' | sort > dir2.txt
$ diff dir1.txt dir2.txt

sedকমান্ড প্রথম ডিরেক্টরির উপাদান সরিয়ে ফেলা হবে Erik`s পোস্টে ধন্যবাদ )


1
আমি বিশ্বাস করি যে এই পদ্ধতিটি সহজ (এখনও তবুও findএকটি মন্তব্য নয় পৃথক উত্তর নয়): cd dir2; find . -exec [ -e ../dir1/{} ] \; -o -print 2>/dev/null এটি dir2 এ উপস্থিত ফাইলগুলি মুদ্রণ করবে তবে dir1 এ উপস্থিত নেই।
আলেকজান্ডার আমেলকিন

5

এটি কিছুটা দেরি হলেও কারও সাহায্য করতে পারে। নিশ্চিত না যে আলাদা বা আরএসসিএনসি কেবল খালি ফাইলের নামগুলি এইভাবে খালি ফর্ম্যাটে ছড়িয়ে দেয়। নীচে আমি প্রসারিত করেছি যে দুর্দান্ত সমাধান দেওয়ার জন্য plhn ধন্যবাদ।

আপনি যদি কেবল ফাইলের নাম চান তবে আপনার পরিষ্কার ফর্ম্যাটে প্রয়োজনীয় ফাইলগুলি অনুলিপি করা সহজ, আপনি ফাইন্ড কমান্ডটি ব্যবহার করতে পারেন।

comm -23 <(find dir1 | sed 's/dir1/\//'| sort) <(find dir2 | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'

এটি ধরে নিয়েছে যে dir1 এবং dir2 উভয়ই একই প্যারেন্ট ফোল্ডারে রয়েছে। সেড কেবলমাত্র মূল ফোল্ডারটি সরিয়ে দেয় যাতে আপনি আপেলগুলির সাথে আপেলগুলির তুলনা করতে পারেন। শেষ সেডটি কেবল d11 নামটি পিছনে ফেলেছে।

আপনি যদি কেবল ফাইলগুলি চান:

comm -23 <(find dir1 -type f | sed 's/dir1/\//'| sort) <(find dir2 -type f | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'

একইভাবে ডিরেক্টরিগুলির জন্য:

comm -23 <(find dir1 -type d | sed 's/dir1/\//'| sort) <(find dir2 -type d | sed 's/dir2/\//'| sort) | sed 's/^\//dir1/'

1
নোট আপনি একটি করতে পারে যে cdসামনে findব্যবহারের থাকার পরিবর্তে sedযেমন,: comm -23 <(cd dir1 || exit; find -type f | sort) <(cd dir2 || exit; find -type f | sort)। ( বর্তমান ডিরেক্টরিটি ব্যবহারে exitবাধা দেওয়ার জন্য findcd
এসগুলি এখানে

এছাড়াও মনে রাখবেন যে নির্দিষ্ট সমাধানের ফাইলগুলি উপস্থিত থাকলে আপনার সমাধানটি ব্যর্থ হতে পারে, যদি আপনার সমর্থনগুলিরcomm সাথে সাম্প্রতিক সংস্করণ থাকে -z( git.savannah.gnu.org/cgit/coreutils.git/commit/… নিয়ে এসেছেন ) আপনি করতে পারেন comm -23 -z <(cd dir1 && find -type f -print0 | sort -z) <(cd dir2 && find -type f -print0 | sort -z)। (ইতিমধ্যে আমি বুঝতে পেরেছিলাম যে exit
এরগুলি

5

গৃহীত উত্তরগুলি উভয় ডিরেক্টরিতে উপস্থিত ফাইলগুলির তালিকাভুক্ত করবে তবে বিভিন্ন সামগ্রী রয়েছে। Dir1 এ বিদ্যমান ফাইলগুলি কেবলমাত্র তালিকাভুক্ত করতে আপনি ব্যবহার করতে পারেন:

diff -r dir1 dir2 | grep 'Only in' | grep dir1 | awk '{print $4}' > difference1.txt

ব্যাখ্যা:

  • diff -r dir1 dir2: তুলনা করুন
  • গ্রেপ 'কেবলমাত্র': এমন লাইনগুলি পান যেখানে 'কেবলমাত্র' থাকে
  • গ্রেপ ডিআর 1: লাইন রয়েছে যেখানে ডির রয়েছে

5

এই উত্তরটি -Dবিকল্প যোগ করে @ অ্যাডেল-জুনিয়রের একটি পরামর্শকে অনুকূল করে তোলে , যা যখন সহায়ক হয় তখন তুলনামূলকভাবে ডিরেক্টরিগুলির মধ্যে গিট রিপোজিটরিগুলি না হয়:

git diff -D --no-index dir1/ dir2/

আপনি যদি ব্যবহার করেন -Dতবে তুলনা দেখতে পাবেন না /dev/null: text Binary files a/whatever and /dev/null differ


দুটি ডিরেক্টরি তুলনা করতে খুব দরকারী, আপনি তত্ক্ষণাত্ ফাইলগুলির মধ্যে পার্থক্য দেখতে পাবেন। অবশ্যই টেক্সট সামগ্রী সহ ফাইলগুলিতে সেরা কাজ করছে।
এরিচ কয়েস্টার

1

ডিআইএফএফ কমান্ড ব্যবহার করে 2 ডিরেক্টরি তুলনা করার একটি সরল উপায়

ফাইল নাম। ফাইল ফাইল .২> ফাইল নাম.ড্যাট >> প্রবেশ করান

রান সম্পন্ন হওয়ার পরে filename.dat খুলুন

এবং আপনি দেখতে পাবেন: কেবল ফাইলের নামেই


কেন আপনি একটি .dat ফাইল আউটপুট করতে হবে?
বিষ্ণু এনকে

1

এটি দুটি ডিরেক্টরি সিঙ্ক করার জন্য কমান্ডগুলি মুদ্রণের জন্য বাশ স্ক্রিপ্ট

dir1=/tmp/path_to_dir1
dir2=/tmp/path_to_dir2
diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2\(.*\): \(.*\)|cp -r $dir2\1/\2 $dir1\1|" |  sed -e "s|Only in $dir1\(.*\): \(.*\)|cp -r $dir1\1/\2 $dir2\1|" 

0

GNU grepবিকল্পের সাহায্যে অনুসন্ধানকে বিপরীত করতে পারে -v। এটি grepলাইনগুলির প্রতিবেদন করে, যা মেলে না। এটির মাধ্যমে আপনি ফাইলগুলির dir2তালিকা থেকে ফাইলগুলি সরাতে পারেন dir1

grep -v -F -x -f <(find dir2 -type f -printf '%P\n') <(find dir1 -type f -printf '%P\n')

বিকল্পগুলি পুরো লাইনে স্ট্রিং অনুসন্ধান করতে -F -xবলে grep

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