দুটি বড় ফাইলের পার্থক্য


14

আমার কাছে "test1.csv" রয়েছে এবং এতে রয়েছে

200,400,600,800
100,300,500,700
50,25,125,310

এবং test2.csv এবং এতে রয়েছে

100,4,2,1,7
200,400,600,800
21,22,23,24,25
50,25,125,310
50,25,700,5

এখন

diff test2.csv test1.csv > result.csv

চেয়ে আলাদা

diff test1.csv test2.csv > result.csv

সঠিক অর্ডারটি কোনটি আমি জানি না তবে আমি অন্য কিছু চাই, উপরের দুটি কমান্ডই এর মতো কিছু তৈরি করবে

2 > 100,4,2,1,7
   3 2,3c3,5
   4 < 100,300,500,700
   5 < 50,25,125,310
   6 \ No newline at end of file
   7 ---
   8 > 21,22,23,24,25
   9 > 50,25,125,310

আমি কেবলমাত্র পার্থক্যটি আউটপুট করতে চাই, ফলাফল.csv এর মতো দেখতে হবে

100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

আমি চেষ্টা diff -qএবং diff -sকিন্তু তারা কৌতুক করতে হয়নি। অর্ডার কোনও বিষয় নয়, কী বিষয় তা হল যে আমি কেবলমাত্র পার্থক্যটি দেখতে চাই, না> না <না <ফাঁকা স্থান।

grep -FvF ছোট ফাইলগুলিতে কৌশলগুলি বড় ফাইলগুলিতে নয় did

প্রথম ফাইলটিতে 5 মিলিয়নেরও বেশি লাইন থাকে, দ্বিতীয় ফাইলটিতে 1300 থাকে।

সুতরাং ফলাফল। CSv এর ফলাফল 4,998,700 লাইনে হওয়া উচিত

আমি চেষ্টা করেছিলাম grep -F -x -v -f যা কার্যকর হয়নি।



1
@ টিম আমি আপনার লিঙ্কটি দেখেছি এবং আমি একজন প্রবীণ সদস্য তাই আমি নিয়মগুলি জানি তবে অযত্ন ছিলাম, দুঃখিত :) এটি সম্পাদনা করছিলাম, এবং আমি একটি পপআপ দেখলাম যে পোস্টটি সম্পাদিত হয়েছিল সুতরাং আপনি আমার জন্য কাজটি করেছেন এবং আমি কৃতজ্ঞ স্যার।
লাইনব

50,25,125,310উভয় ফাইলের মধ্যেই সাধারণ .. আপনার এটি আপনার পছন্দসই আউটপুট থেকে অপসারণ করতে হবে ..
হিমাইল

অর্ডার সংরক্ষণ করা উচিত?
কোস

1
বাছাই করা তথ্য আপনি কী করতে চান তার উপর নির্ভর করে, আইএমও, প্যাচ তৈরির জন্য f যে কোনও হারে, আমি এখন আপনার সেরা সরঞ্জাম, ডিফ, গ্রেপ, অ্যাজক বা পার্ল সম্পর্কে নিশ্চিত।
প্যান্থার

উত্তর:


20

এর জন্য একটি কাজের মতো শোনাচ্ছে comm:

$ comm -3 <(sort test1.csv) <(sort test2.csv)
100,300,500,700
    100,4,2,1,7
    21,22,23,24,25
    50,25,700,5

হিসাবে ব্যাখ্যা করা হয়েছে man comm:

   -1     suppress column 1 (lines unique to FILE1)

   -2     suppress column 2 (lines unique to FILE2)

   -3     suppress column 3 (lines that appear in both files)

সুতরাং, এর -3অর্থ হ'ল কেবলমাত্র লাইনগুলি যে কোনও একটিতে অনন্য printed ফাইলগুলি মুদ্রিত হবে। তবে যে ফাইলগুলিতে তাদের পাওয়া গিয়েছিল সেগুলি অনুসারে এগুলি ইন্টেন্ট করা রয়েছে the ট্যাবটি সরাতে, ব্যবহার করুন:

$ comm -3 <(sort test1.csv) <(sort test2.csv) | tr -d '\t'
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

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

comm -3 test1.csv test2.csv | tr -d '\t' > difference.csv

আপনি 200,[...]লাইন হু পরে ফাঁকা স্থান দ্বারা বোকা হয়নি ? :)
কোস

@ কোস না, আমি প্রথমে ফাইলগুলি থেকে ফাঁকা স্থানগুলি সরিয়েছি। আমি ধরে নিয়েছিলাম যে ওপি-র ফাইলগুলি আসলে নেই actually
টেরডন

6

প্রক্রিয়া প্রতিস্থাপনের grepসাথে ব্যবহার bash:

$ cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv)
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

আউটপুট হিসাবে সংরক্ষণ করুন results.csv:

cat <(grep -vFf test2.csv test1.csv) <(grep -vFf test1.csv test2.csv) >results.csv
  • <()হয় bashপ্রক্রিয়া প্রতিকল্পন প্যাটার্ন

  • grep -vFf test2.csv test1.csv রেখাগুলি কেবল অনন্যরূপে খুঁজে পাবে test1.csv

  • grep -vFf test1.csv test2.csv রেখাগুলি কেবল অনন্যরূপে খুঁজে পাবে test2.csv

  • শেষ পর্যন্ত আমরা ফলাফলগুলি সংক্ষিপ্ত করছি cat

অথবা অলি যেমন পরামর্শ দিয়েছেন , আপনি কমান্ড গ্রুপিংও ব্যবহার করতে পারেন:

$ { grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv; }
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

বা কেবল একের পর এক চালান, কারণ তারা উভয়ই STDOUT এ লিখছেন তারা শেষ পর্যন্ত যুক্ত হবে:

$ grep -vFf test2.csv test1.csv; grep -vFf test1.csv test2.csv
100,300,500,700
100,4,2,1,7
21,22,23,24,25
50,25,700,5

1
catদুটি নির্দেশিত আদেশ কেন ? কেন শুধু একজন চালাবেন না অন্যজন? grep ... ; grep ...বা { grep ... ; grep ... ; }যদি আপনি সম্মিলিত আউটপুট দিয়ে কিছু করতে চান।
অলি

@ অলি ধন্যবাদ..এই দুর্দান্ত ধারণা..আমি তা ভেবে
দেখিনি

4

যদি সারিগুলির ক্রম প্রাসঙ্গিক না হয় তবে ব্যবহার করুন awkবা perl:

awk '{seen[$0]++} END {for (i in seen) {if (seen[i] == 1) {print i}}}' 1.csv 2.csv

grepসাধারণ লাইনগুলি পেতে এবং সেগুলি ফিল্টার করতে ব্যবহার করুন :

grep -hxvFf <(grep -Fxf 1.csv 2.csv) 1.csv 2.csv

অভ্যন্তরীণ গ্রেপগুলি সাধারণ লাইনগুলি পায়, তারপরে বাহ্যিক গ্রেপগুলি এমন লাইনগুলি খুঁজে পায় যা এই সাধারণ লাইনের সাথে মেলে না।


আপনার awk কমান্ডটি কেবল পুনরায় প্রয়োগ করে sort | uniq -u, যখন কোনও ফাইলটিতে নকল লাইন থাকে তখন ভুল উত্তর দেয়। গ্রেপের জন্য, আমি "অভ্যন্তরীণ" / "বাহ্যিক" বলব, "অভ্যন্তরীণ" / "বাহ্যিক" না।
পিটার কর্ডেস

@ পিটারকর্ডস হ্যাঁ, এটি করে এবং আপনি কে এটির ভুল ফলাফল বলেছিলেন?
মুড়ু

এই অর্থে ভুল যে এই কোণার ক্ষেত্রে প্রশ্নটি যা চেয়েছিল ঠিক তাই নয়। এটি কোনও ব্যক্তি যা চায় তা হতে পারে তবে আপনার কী awkপ্রিন্ট করবে এবং কোনটি comm -3এবং diffউত্তরগুলি মুদ্রণ করবে তার মধ্যে পার্থক্যটি চিহ্নিত করা উচিত ।
পিটার কর্ডেস

@ পিটারকর্ডস আবার, আপনি কে এটি বলবেন? যতক্ষণ না ওপি তারা যা চায় তা না বলা পর্যন্ত, আউটপুট এর চেয়ে আলাদা হয় কিনা সে বিষয়ে আমি চিন্তা করি না comm -3। আমার কেন এটি ব্যাখ্যা করা উচিত তার কোনও কারণ আমি দেখতে পাচ্ছি না । আপনি যদি কোনও নোটটিতে সম্পাদনা করতে চান তবে নির্দ্বিধায়।
মুরু

ওপি জানিয়েছে যে সে পার্থক্য চায়। আপনার প্রোগ্রাম যেটি তৈরি করে তা সর্বদা হয় না। একটি প্রোগ্রাম যা একটি টেস্টকেসের জন্য একই আউটপুট উত্পাদন করে তবে সমস্ত ক্ষেত্রে লেখা হিসাবে বর্ণনাটি পূরণ করে না, একটি মাথা আপ প্রয়োজন a আমি এখানে বলতে চাই এবং আমি কে বা আপনি কে তা নির্বিশেষে এটি সত্য it's আমি একটি নোট যুক্ত করেছি।
পিটার কর্ডেস

4

এর --*-line-format=...বিকল্পগুলি ব্যবহার করুনdiff

diffআপনার যা প্রয়োজন ঠিক তা বলতে পারেন - নীচে ব্যাখ্যা করেছেন:

diff --old-line-format='%L' --new-line-format='%L' --unchanged-line-format='' f1.txt f2.txt

একটি printfসংখ্যা বিন্যাসের অনুরূপ খুব বিশদভাবে ডিফের আউটপুট নির্দিষ্ট করা সম্ভব ।

প্রথম ফাইলের লাইনগুলিকে test1.csvবলা হয় "পুরাতন" লাইন এবং দ্বিতীয়টি থেকে প্রাপ্ত রেখাগুলি test2.csv"নতুন" লাইন। diffকোনও ফাইলের মধ্যে কী পরিবর্তন হয়েছে তা দেখার জন্য এটি কখন ব্যবহৃত হয় তা বোঝা যায় ।

আমাদের প্রয়োজনীয় বিকল্পগুলি হ'ল "পুরানো" লাইন, "নতুন" লাইন এবং "অপরিবর্তিত" লাইনগুলির ফর্ম্যাট সেট করে।
আমাদের যে ফর্ম্যাটগুলির প্রয়োজন তা খুব সহজ:
পরিবর্তিত রেখাগুলির জন্য, নতুন এবং পুরানো, আমরা কেবল লাইনের পাঠ্য আউটপুট করতে চাই। %Lলাইন পাঠ্যের বিন্যাস প্রতীক।
অপরিবর্তিত লাইনের জন্য, আমরা কিছুই দেখাতে চাই না।

এটির সাহায্যে আমরা পছন্দ মতো বিকল্পগুলি লিখতে পারি --old-line-format='%L'এটির সাহায্যে আমরা আপনার উদাহরণ ডেটা ব্যবহার করে এর এবং এগুলিকে একসাথে রাখতে পারি:

$ diff --old-line-format='%L' --new-line-format='%L' --unchanged-line-format='' test1.csv test2.csv
100,4,2,1,7
100,300,500,700
21,22,23,24,25
50,25,700,5


পারফরম্যান্স নোট

যেহেতু ফাইলগুলির আকার পৃথক পৃথক, ইনপুট ফাইলগুলি যদি কোনও বিষয় না আসে তা আদান-প্রদানের চেষ্টা করুন, এটি এমন হতে পারে যে অভ্যন্তরীণ অভ্যন্তরীণ কাজগুলি অন্য উপায়ের diffচেয়ে এক উপায়ে ভাল পরিচালনা করতে পারে। ভাল হয় কম স্মৃতি প্রয়োজন, বা কম গণনা প্রয়োজন।

ব্যবহারের জন্য একটি অপ্টিমাইজেশন বিকল্প রয়েছে diff বড় ফাইল সঙ্গে --speed-large-files। এটি ফাইলের কাঠামো সম্পর্কে অনুমানগুলি ব্যবহার করে, সুতরাং এটি আপনার ক্ষেত্রে সহায়তা করে কিনা তা পরিষ্কার নয়, তবে এটি চেষ্টা করার মতো worth

বিন্যাস বিকল্পগুলি নীচে বর্ণিত man diffহয় --LTYPE-line-format=LFMT


3

যেহেতু আদেশ সংরক্ষণ করার প্রয়োজন নেই, কেবল:

sort test1.csv test2.csv | uniq -u
  • sort test1.csv test2.csv: একত্রীকরণ এবং বাছাই test1.csvএবংtest2.csv
  • uniq -u: কেবলমাত্র সেই লাইনগুলি মুদ্রণ করে যার কোনও সদৃশ নেই

এটি কোনও কাজ করে না যদি একটি ফাইলে দু'বার লাইন থাকে, যা অন্য ফাইলে প্রদর্শিত না হয়। উভয় ঘটনা একটি diffফল হতে হবে ।
ভোলকার সিগেল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.