দুটি ফাইলের দুটি কলামের তুলনা করুন এবং এটি মেলে তবে মুদ্রণ করুন


16

আমি সোলারিস 10 ব্যবহার করছি এবং তাই গ্রাফিক অপশনগুলি কাজ করে না -

আমার কাছে দুটি পাইপ-বিচ্ছিন্ন ফাইল রয়েছে:

file1:

abc|123|BNY|apple|
cab|234|cyx|orange|
def|kumar|pki|bird|

ফাইল 2:

abc|123|
kumar|pki|
cab|234

আমি ফাইল 2 এর প্রথম দুটি কলামকে ফাইল 1 এর সাথে তুলনা করতে চাই (প্রথম দুটি কলামে ফাইল 1 এর পুরো বিষয়বস্তু সন্ধান করুন) যদি তারা ফাইল 1 এর সাথে মেলে লাইনটি মুদ্রণ করে। তারপরে ফাইল 2 এর দ্বিতীয় লাইনটি অনুসন্ধান করুন।

প্রত্যাশিত আউটপুট:

abc|123|BNY|apple|
cab|234|cyx|orange|

আমার কাছে থাকা ফাইলগুলি প্রায় 400,000 লাইনযুক্ত বিশাল, তাই আমি দ্রুত কার্যকর করতে চাই execution


আমি আপনার উদাহরণগুলি থেকে নেতৃস্থানীয় স্পেসগুলি সরিয়েছি, আপনি যদি এটি চান তবে দয়া করে সম্পাদনাটি আবার রোল করুন। মনে রাখবেন যে স্পেসগুলি তাৎপর্যপূর্ণ, আপনার যদি সেগুলি আপনার প্রকৃত ফাইলগুলিতে থাকে তবে তা কেবল আপনার উচিত।
টেরডন

grepএটির অধীনে জিএনইউ সংস্করণটি ব্যবহার করার চেষ্টা করুন /usr/sfw/bin/ggrepstackoverflow.com/questions/15259882/…
slm

উত্তর:


21

এই কিসের জন্য প্রস্তুত করা হয়েছিল:

$ awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0' file2 file1
abc|123|BNY|apple|
cab|234|cyx|orange|

ব্যাখ্যা

  • -F'|': ক্ষেত্র বিভাজককে সেট করে |
  • NR==FNR: এনআর হ'ল বর্তমান ইনপুট লাইন নম্বর এবং এফএনআর বর্তমান ফাইলের লাইন নম্বর। দু'টি তখনই সমান হবে যখন ১ ম ফাইলটি পড়া হচ্ছে।
  • c[$1$2]++; next: এটি যদি ১ ম ফাইল হয় তবে cঅ্যারেতে প্রথম দুটি ক্ষেত্র সংরক্ষণ করুন । তারপরে, পরবর্তী লাইনে এড়িয়ে যান যাতে এটি কেবলমাত্র 1 ম ফাইলে প্রয়োগ করা হয়।

  • c[$1$2]>0: অন্য ব্লকটি কেবল তখনই চালিত হবে যদি এটি দ্বিতীয় ফাইল হয় তাই আমরা এই ফাইলটির 1 এবং 2 ক্ষেত্রটি ইতিমধ্যে দেখা গেছে কিনা তা পরীক্ষা করে দেখি ( c[$1$2]>0) এবং সেগুলি থাকলে, আমরা লাইনটি মুদ্রণ করি। ইন awk, ডিফল্ট ক্রিয়াটি লাইনটি প্রিন্ট করা হয় যদি c[$1$2]>0সত্য হয় তবে লাইনটি মুদ্রণ করা হবে।


বিকল্প হিসাবে, যেহেতু আপনি পার্লের সাথে ট্যাগ করেছেন:

perl -e 'open(A, "file2"); while(<A>){/.+?\|[^|]+/ && $k{$&}++};
         while(<>){/.+?\|[^|]+/ && do{print if defined($k{$&})}}' file1

ব্যাখ্যা

প্রথম লাইনটি খুলবে file2, ২ য় |( .+?\|[^|]+) অবধি সমস্ত কিছু পড়বে এবং হ্যাশটিতে এটি ( $&শেষ ম্যাচের অপারেটরের ফলাফল ) সংরক্ষণ করবে %k

দ্বিতীয় লাইনটি ফাইল 1 প্রক্রিয়া করে, 1 ম দুটি কলাম আহরণ করতে একই রেজেক্স ব্যবহার করে এবং যদি এই কলামগুলি হ্যাশে সংজ্ঞায়িত করা হয় তবে লাইনটি মুদ্রণ করুন %k


উপরোক্ত দুটি পদ্ধতিরই মেমরির মধ্যে ফাইল 2 এর 2 টি প্রথম কলাম ধারণ করতে হবে। আপনার যদি কয়েকটি কয়েক লক্ষ লাইন থাকে তবে সমস্যাটি হওয়া উচিত নয় তবে এটি যদি হয় তবে আপনি এর মতো কিছু করতে পারেন

cut -d'|' -f 1,2 file2 | while read pat; do grep "^$pat" file1; done

তবে তা ধীর হবে।


কিন্তু এটি কি সমস্ত (প্রথম দুটি কলাম) file2মেমরিতে লোড করবে না ?
জোসেফ আর

@terdon: awk -F'|' 'NR==FNR{c[$1$2]++;next};c[$1$2] > 0'সংক্ষিপ্ত সংস্করণ।
কিউংলম

এটি কাজ করে না ..
user68365

@ user68365: file2নকল সারি আছে?
কিউংলম

এটির কোনও সদৃশ সারি নেই
ব্যবহারকারী 68365

1

আমি মনে করি

grep -Ff file2 file1

আপনি যা খুঁজছেন এটি দক্ষ হওয়া উচিত, তবে আমি নিশ্চিত নই যে এটি আপনি চান ঠিক ততটাই সঠিক হবে। যদি abc|123(উদাহরণস্বরূপ) file1বিভিন্ন কলামের একটি লাইনে পাওয়া যায় , তবে সেই লাইনটিও মুদ্রিত হবে। যদি আপনি গ্যারান্টি দিতে পারেন যে এটি কখনও ঘটবে না, উপরের লাইনের কাজ করা উচিত।


গ্রেপ যথেষ্ট হবে না, যেহেতু abc | 123 তম ফাইলের কোথাও উপস্থিত থাকতে পারে। তাছাড়া আমি সোলারিস 10 ব্যবহার করছি এবং আমি সেই গ্রেপ বিকল্পটিও ব্যবহার করতে পারছি না।
ব্যবহারকারী 68365

2
@ user68365 দয়া করে আপনার প্রশ্নে এই সমস্ত পরিষ্কার করুন। আপনাকে আমাদের আপনার ওএস বলতে হবে এবং নির্দিষ্ট করতে হবে যে আপনি কেবল প্রথম 2 টি কলামের সাথে মেলে।
টেরডন

1

যদি আপনি এসকিউএল-তে সমস্যাটি ভাবতে চান তবে অবশ্যই আপনার ' কিউ ' নামের একটি সরঞ্জামটি চেষ্টা করা উচিত :

$ q -d '|' "select f1.* from file1 f1 join file2 f2 on (f1.c1 = f2.c1 and f1.c2 = f2.c2)"

আপনি এসকিউএল কোয়েরির সাথে পরিচিত কিনা তা আরও স্পষ্ট এবং বোঝা সহজ।


এতদূর স্বল্পতম ক্রিপ্টিক সমাধানগুলির জন্য আপনাকে ধন্যবাদ। এটাই সেটা যা আমি চাই. তবে এই "কিউ সরঞ্জাম "টি
রল্ফ

খুব দরকারী সরঞ্জাম।
ghilesZ

0
$  sed 's/^/\^/' 2.txt > temp.txt ; grep 1.txt -f temp.txt
abc|123|BNY|apple|
cab|234|cyx|orange|

1
আমি যেমন সম্পাদনা করেছি এবং প্রশ্নটিতে উল্লেখ করেছি,
গ্রেপ

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