লিনাক্স টার্মিনালে দুটি ফাইলের তুলনা করা


168

"A.txt" এবং "b.txt" নামে দুটি ফাইল রয়েছে শব্দের একটি তালিকা রয়েছে। এখন আমি "a.txt" এ কোন শব্দ অতিরিক্ত এবং "b.txt" এ নেই তা যাচাই করতে চাই ।

আমার দুটি অভিধানের তুলনা করার জন্য আমার একটি দক্ষ অ্যালগরিদম প্রয়োজন।


27
diff a.txt b.txtযথেষ্ট না?
থ্যাঙ্কসফোরআলএফফিশ

শব্দগুলি প্রতিটি ফাইলে কয়েকবার আসতে পারে? আপনি ফাইল বাছাই করতে পারেন?
বেসিল স্টারিনকিভিচ

আমার কেবল সেই শব্দগুলি দরকার যা "বি টেক্সট" এ উপস্থিত নেই এবং একটি টেক্সটে উপস্থিত রয়েছে
আলী ইমরান

উত্তর:


343

আপনি যদি ভিএম ইনস্টল করে থাকেন তবে এটি ব্যবহার করে দেখুন:

vimdiff file1 file2

অথবা

vim -d file1 file2

আপনি এটি দুর্দান্ত দেখতে পাবেন।এখানে চিত্র বর্ণনা লিখুন


9
স্পষ্টতই দুর্দান্ত, নকশায় ভাল এবং ভিন্নতাগুলি খুঁজে পাওয়া সহজ। ওহমিগড
জেন

1
আপনার উত্তর সন্ত্রস্ত, কিন্তু আমার শিক্ষক আমাকে প্রয়োজনীয় কোনো লাইব্রেরি ফাংশন ব্যবহার না করার: পি
আলী ইমরান

1
কি দুর্দান্ত সরঞ্জাম! এটি অত্যন্ত সহায়ক।
ব্যবহারকারী1205577

1
এই রঙগুলির অর্থ কী?
zygimantus

1
কোডযুক্ত রঙের অর্থ তারা দুটি ফাইলে আলাদা। @zygimantus
ফেংগিয়া লি

73

এগুলি বাছাই করুন এবং ব্যবহার করুন comm:

comm -23 <(sort a.txt) <(sort b.txt)

comm(সাজানো) ইনপুট ফাইলগুলির তুলনা করে এবং ডিফল্টরূপে তিনটি কলাম আউটপুট দেয়: লাইন যা একটির জন্য অনন্য, খগুলির জন্য স্বতন্ত্র লাইন এবং উভয়টিতে উপস্থিত লাইনগুলি। নির্দিষ্ট করে -1, -2এবং / অথবা -3আপনি সংশ্লিষ্ট আউটপুট দমন করতে পারেন। অতএব comm -23 a bকেবলমাত্র এন্ট্রিগুলির তালিকাবদ্ধ করে যা ক। আমি <(...)ফ্লাইটে ফাইলগুলি বাছাই করতে সিনট্যাক্সটি ব্যবহার করি , যদি সেগুলি ইতিমধ্যে সাজানো থাকে তবে আপনার এটির দরকার নেই।


আমি কেবল গ্রেপ কমান্ড ব্যবহার করে নিজের উত্তর যুক্ত করেছি, দয়া করে আমাকে বলুন এটি আরও দক্ষ?
আলী ইমরান

3
@ অলিমন, commআরও দক্ষ কারণ এটি পুরো ফাইলটিকে স্মৃতিতে না সঞ্চয় করে একক রান করে কাজ করে। যেহেতু আপনি সম্ভবত ইতিমধ্যে বাছাই করা অভিধানগুলি ব্যবহার করছেন তবে আপনার এগুলির প্রয়োজনও sortনেই। grep -f file1 file2অন্যদিকে ব্যবহার করা সম্পূর্ণ file1স্মৃতিতে লোড করবে এবং প্রতিটি লাইনকে file2সেই সমস্ত এন্ট্রিগুলির সাথে তুলনা করবে , যা অনেক কম দক্ষ। এটি বেশিরভাগ ক্ষেত্রে ছোট, অরসোর্টডের জন্য দরকারী -f file1
অ্যান্ডারস জোহানসন

1
"কম" কমান্ডটি ভাগ করে নেওয়ার জন্য @ অ্যান্ডারস জোহানসনকে ধন্যবাদ। সত্যিই এর নিফটি। আমাকে প্রায়শই ফাইলগুলির মধ্যে বাইরের সাথে যোগ দিতে হয় এবং এটি কৌশলটি করে।
blispr

নতুন লাইন চরিত্রের দিকে মনোযোগ দিন ... আমি সবেমাত্র পেয়েছি যে \nতুলনা করতে অন্তর্ভুক্ত করা হবে।
বিন


28

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

প্রতিটি বিকল্পের জন্য প্রাসঙ্গিক গ্রুপ নির্বাচন করতে নিম্নলিখিত তিনটি বিকল্প ব্যবহার করতে পারে:

  • '% <' FILE1 থেকে লাইন পান

  • '%>' FILE2 থেকে লাইন পান

  • উভয় ফাইল থেকে লাইন সরানোর জন্য '' (খালি স্ট্রিং)।

উদাহরণস্বরূপ: পৃথক - পরিবর্তন-গোষ্ঠী-বিন্যাস = "% <" - অদলবদল-গোষ্ঠী-বিন্যাস = "" file1.txt ফাইল2.txt

[root@vmoracle11 tmp]# cat file1.txt 
test one
test two
test three
test four
test eight
[root@vmoracle11 tmp]# cat file2.txt 
test one
test three
test nine
[root@vmoracle11 tmp]# diff --changed-group-format='%<' --unchanged-group-format='' file1.txt file2.txt 
test two
test four
test eight

27

আপনি যদি পৃথক আউটপুট শৈলী থেকে পছন্দ করেন তবে গিট সংগ্রহস্থলে নয় ফাইলগুলি তুলনা করতে আপনি পতাকাটির git diffসাথে এটি ব্যবহার করতে পারেন --no-index:

git diff --no-index a.txt b.txt

প্রতিটি প্রায় 200k ফাইলের নাম স্ট্রিং সহ কয়েকটি ফাইল ব্যবহার করে আমি বেঞ্চমার্ক করেছিলাম (বিল্ট-ইন timeকমান্ড সহ) এই পদ্ধতির তুলনায় এখানে অন্যান্য উত্তরগুলির কয়েকটি বনাম:

git diff --no-index a.txt b.txt
# ~1.2s

comm -23 <(sort a.txt) <(sort b.txt)
# ~0.2s

diff a.txt b.txt
# ~2.6s

sdiff a.txt b.txt
# ~2.7s

vimdiff a.txt b.txt
# ~3.2s

comm এখনও পর্যন্ত দ্রুততম বলে মনে হচ্ছে git diff --no-index বলে মনে হচ্ছে এটি বিভিন্ন ধরণের আউটপুটের জন্য দ্রুততম পদ্ধতির বলে মনে হচ্ছে।


2018-03-25 আপডেট করুন আপনি --no-indexযদি গিট সংগ্রহস্থলের অভ্যন্তরে না থাকেন এবং rep ভান্ডারটির মধ্যে অপ্রকাশিত ফাইলগুলি তুলনা করতে না চান তবে আপনি প্রকৃতপক্ষে পতাকাটি বাদ দিতে পারেন । থেকে man পৃষ্ঠা :

এই ফর্মটি ফাইল সিস্টেমে প্রদত্ত দুটি পাথের তুলনা করা। গিট দ্বারা নিয়ন্ত্রিত একটি কার্যনির্বাহী গাছে কমান্ড চালাবার সময় এবং কার্যকরী গাছের বাইরে কমপক্ষে একটি পথ নির্দেশ করে বা গিট দ্বারা নিয়ন্ত্রিত একটি কার্যক্ষম গাছের বাইরে কমান্ড চালানোর সময় আপনি --no-index বিকল্পটি বাদ দিতে পারেন।


9

আপনি ব্যবহার করতে পারেন: কলর্ডিফ : রঙের সাথে আউটপুট প্রদর্শন করে।

ভিমডিফ সম্পর্কে : এটি আপনাকে এসএসএইচের মাধ্যমে ফাইলগুলির তুলনা করতে দেয়, উদাহরণস্বরূপ:

vimdiff /var/log/secure scp://192.168.1.25/var/log/secure

থেকে নেওয়া হয়েছে: http://www.sysadmit.com/2016/05/linux-diferencias-entre-dos-archivos.html



4

ব্যবহার করুন comm -13 (বাছাই করা ফাইলগুলির প্রয়োজন) :

$ cat file1
one
two
three

$ cat file2
one
two
three
four

$ comm -13 <(sort file1) <(sort file2)
four

1

এটির জন্য আমার সমাধানটি এখানে:

mkdir temp
mkdir results
cp /usr/share/dict/american-english ~/temp/american-english-dictionary
cp /usr/share/dict/british-english ~/temp/british-english-dictionary
cat ~/temp/american-english-dictionary | wc -l > ~/results/count-american-english-dictionary
cat ~/temp/british-english-dictionary | wc -l > ~/results/count-british-english-dictionary
grep -Fxf ~/temp/american-english-dictionary ~/temp/british-english-dictionary > ~/results/common-english
grep -Fxvf ~/results/common-english ~/temp/american-english-dictionary > ~/results/unique-american-english
grep -Fxvf ~/results/common-english ~/temp/british-english-dictionary > ~/results/unique-british-english

2
আপনি কি অন্য কোনও সমাধান চেষ্টা করেছেন? এই সমাধানগুলির মধ্যে একটি আপনার পক্ষে কার্যকর ছিল? আপনার প্রশ্নটি অনেক ব্যবহারকারীর কাছে আঁকার পক্ষে যথেষ্ট সাধারণ, তবে আপনার উত্তরটি আমার স্বাদের জন্য আরও সুনির্দিষ্ট ... কারণ আমার বিশেষ ক্ষেত্রেটি কার্যকর sdiff -s file1 file2ছিল।
মেটাফানিয়েল

@ মেটাফানিয়েল আমার সমাধান এসডিফ কমান্ড ব্যবহার করবেন না। সমস্যাটি সমাধান করার জন্য এটি কেবলমাত্র কমান্ড ইন কমান্ড ব্যবহার করে।
আলী ইমরান

-1

এর জন্য awk ব্যবহার করা। পরীক্ষা ফাইলগুলি:

$ cat a.txt
one
two
three
four
four
$ cat b.txt
three
two
one

দ্য উইন্ড:

$ awk '
NR==FNR {                    # process b.txt  or the first file
    seen[$0]                 # hash words to hash seen
    next                     # next word in b.txt
}                            # process a.txt  or all files after the first
!($0 in seen)' b.txt a.txt   # if word is not hashed to seen, output it

সদৃশগুলি আউটপুটড:

four
four

সদৃশগুলি এড়ানোর জন্য, প্রতিটি সদ্য পাওয়া শব্দটি a.txt এ হ্যাশে যুক্ত করুন seen:

$ awk '
NR==FNR {
    seen[$0]
    next
}
!($0 in seen) {              # if word is not hashed to seen
    seen[$0]                 # hash unseen a.txt words to seen to avoid duplicates 
    print                    # and output it
}' b.txt a.txt

আউটপুট:

four

শব্দ তালিকাটি যদি কমা দ্বারা পৃথক করা হয় তবে:

$ cat a.txt
four,four,three,three,two,one
five,six
$ cat b.txt
one,two,three

আপনাকে কয়েকটি অতিরিক্ত ল্যাপস ( forলুপস) করতে হবে:

awk -F, '                    # comma-separated input
NR==FNR {
    for(i=1;i<=NF;i++)       # loop all comma-separated fields
        seen[$i]
    next
}
{
    for(i=1;i<=NF;i++)
        if(!($i in seen)) {
             seen[$i]        # this time we buffer output (below):
             buffer=buffer (buffer==""?"":",") $i
        }
    if(buffer!="") {         # output unempty buffers after each record in a.txt
        print buffer
        buffer=""
    }
}' b.txt a.txt

এবার আউটপুট:

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