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


529

ধরুন আমার কাছে নীচের মতো ফাইল রয়েছে:

123 
123 
234 
234 
123 
345

আমি খুঁজে পেতে চাই যে '123' কতবার নকল হয়েছিল, কতবার '234' নকল হয়েছিল, ইত্যাদি। সুতরাং আদর্শভাবে, আউটপুটটি এরকম হবে:

123  3 
234  2 
345  1

4
আপনি কোন ভাষাটি ব্যবহার করতে চান?
ভিএমএটিএম

উত্তর:


791

ধরে নিই যে প্রতি লাইনে একটি নম্বর রয়েছে:

sort <file> | uniq -c

আপনি আরও ভার্বোজ ব্যবহার করতে পারেন --count জিএনইউ সংস্করণ যেমন লিনাক্সে পতাকা :

sort <file> | uniq --count

3
এটি আমি যা করি তবে অ্যালগরিদমিকভাবে এটি সর্বাধিক দক্ষ পদ্ধতির (O (n লগ এন) * avg_line_len যেখানে n লাইন সংখ্যা) বলে মনে হয় না। আমি বেশ কয়েকটি গিগাবাইট বড় ফাইলগুলিতে কাজ করছি তাই পারফরম্যান্স একটি মুখ্য বিষয়। আমি আশ্চর্য হয়েছি যে এমন কোনও সরঞ্জাম আছে যা কেবলমাত্র একটি উপগ্রী গাছ ব্যবহার করে একক পাসে গণনা করে (আমার ক্ষেত্রে স্ট্রিংগুলিতে প্রায়শই সাধারণ উপসর্গ থাকে) বা অনুরূপ, এটি O (n) * avg_line_len এ কৌশলটি করা উচিত। এমন কমান্ডলাইন সরঞ্জামটি কি কেউ জানেন?
Droggl

21
একটি অতিরিক্ত পদক্ষেপ হ'ল এর আউটপুটটিকে একটি চূড়ান্ত 'সাজানো-এন' কমান্ডে পাইপ করা। এটি ফলাফলগুলি বাছাই করবে যার মাধ্যমে লাইনগুলি প্রায়শই ঘটে।
সমোজ

79
আপনি যদি কেবল সদৃশ লাইনগুলি মুদ্রণ করতে চান তবে '
ইউনিক

6
আপনি যদি আবার ফলাফলটি বাছাই করতে চান তবে আপনি আবার ব্যবহার sortকরতে পারেন:sort <file> | uniq -c | sort -n
অভিষেক কাশ্যপ

413

এটি কেবল সদৃশ লাইনগুলি প্রিন্ট করবে :

sort FILE | uniq -cd

বা, জিএনইউ দীর্ঘ বিকল্পের সাথে (লিনাক্সে):

sort FILE | uniq --count --repeated

উপর বাসদ এবং ওএসএক্স আপনি, grep ব্যবহার করতে হবে অনন্য লাইন ফিল্টার করার জন্য:

sort FILE | uniq -c | grep -v '^ *1 '

প্রদত্ত উদাহরণের জন্য, ফলাফলটি হবে:

  3 123
  2 234

আপনি যদি কেবল একবারে প্রদর্শিত হয় সেগুলি সহ সমস্ত লাইনের জন্য মুদ্রণ করতে চান :

sort FILE | uniq -c

বা, জিএনইউ দীর্ঘ বিকল্পের সাথে (লিনাক্সে):

sort FILE | uniq --count

প্রদত্ত ইনপুটটির জন্য, আউটপুটটি হ'ল:

  3 123
  2 234
  1 345

অর্ডার করার জন্য আউটপুট সাজাতে উপরে অধিকাংশ ঘন লাইন সঙ্গে, আপনি (সমস্ত ফলাফল পেতে) নিম্নলিখিতগুলি করতে পারেন:

sort FILE | uniq -c | sort -nr

বা, কেবলমাত্র অনুলিপি লাইন পেতে, সর্বাধিক ঘন ঘন:

sort FILE | uniq -cd | sort -nr

ওএসএক্স এবং বিএসডি-তে চূড়ান্ত হয়:

sort FILE | uniq -c | grep -v '^ *1 ' | sort -nr

1
--Repected বা -d বিকল্পের সাথে ভাল পয়েন্ট। "| গ্রেপ 2" বা অনুরূপ ব্যবহার করার চেয়ে অনেক বেশি নির্ভুল!
লৌরী

যার পুনরাবৃত্তির সংখ্যা 100 এরও বেশি সেই সমস্ত লাইন পুনরুদ্ধার করতে আমি এই আদেশটি কীভাবে সংশোধন করতে পারি?
ব্ল্যাক_আডার

@ ব্ল্যাক_আাইডার যুক্ত করা | sort -nবা | sort -nrপাইপে পুনরাবৃত্তি গণনা (যথাক্রমে আরোহণ বা উতরাই ) দ্বারা আউটপুটটিকে সাজান। এটি যা আপনি জিজ্ঞাসা করছেন তা নয় তবে আমি ভেবেছিলাম এটি সাহায্য করতে পারে।
Andrea

1
@ ব্ল্যাক_রিডার অ্যাজক সমস্ত ধরণের গণনা করতে সক্ষম বলে মনে হচ্ছে: আপনার ক্ষেত্রে আপনি করতে পারেন| awk '$1>100'
আন্দ্রে

4
@ ফিওনবিও দেখে মনে হচ্ছে আপনি ওএসএক্স ইউনিকে একসাথে -c এবং -d ব্যবহার করতে পারবেন না । নির্দেশ করার জন্য ধন্যবাদ। আপনি অনন্য লাইনগুলি ফিল্টার করতে গ্রেপ ব্যবহার করতে পারেন :sort FILE | uniq -c | grep -v '^ *1 '
Andrea

72

একাধিক ফাইলে নকল লাইনগুলি সন্ধান এবং গণনা করতে, আপনি নিম্নলিখিত আদেশটি চেষ্টা করতে পারেন:

sort <files> | uniq -c | sort -nr

বা:

cat <files> | sort | uniq -c | sort -nr

30

এর মাধ্যমে :

awk '{dups[$1]++} END{for (num in dups) {print num,dups[num]}}' data

ইন awk 'dups[$1]++'কমান্ড পরিবর্তনশীল $1COLUMN1 সমগ্র সামগ্রী ঝুলিতে এবং বর্গাকার বন্ধনী অ্যারের এক্সেস আছে। সুতরাং, dataফাইলের প্রতিটি লাইনের প্রথম কলামের জন্য , নামের অ্যারের নোড dupsবৃদ্ধি করা হয়।

এবং শেষে, আমরা ভেরিয়েবলের dupsসাথে অ্যারের উপরে লুপ করছি numএবং সেভ করা সংখ্যাগুলি প্রথমে মুদ্রণ করুন তারপরে তাদের নকল মানের সংখ্যাটি dups[num]

মনে রাখবেন যে আপনার ইনপুট ফাইলটির কয়েকটি লাইনের শেষে ফাঁকা জায়গা রয়েছে, যদি আপনি সেগুলি সাফ করেন, আপনি উপরের কমান্ডের $0জায়গায় ব্যবহার করতে পারেন $1:)


1
আমাদের যে বিবেচনা করে এটি কি ওভারকিল কিছুটা নয় uniq?
নাথান ফেলম্যান

9
sort | uniqএবং অ্যাজকের সমাধানটিতে বেশ আলাদা পারফরম্যান্স এবং রিসোর্স ট্রেড-অফ রয়েছে: ফাইলগুলি যদি বড় হয় এবং বিভিন্ন লাইনের সংখ্যা কম হয় তবে আঙ্ক সমাধানটি আরও কার্যকর। এটি লাইনের সংখ্যায় লিনিয়ার এবং স্থান ব্যবহার বিভিন্ন লাইনের সংখ্যায় লিনিয়ার। OTOH, awk সমাধানটির জন্য মেমরিতে সমস্ত ভিন্ন লাইন রাখা দরকার, যখন (GNU) বাছাই করা টেম্প ফাইলগুলি অবলম্বন করতে পারে।
লার্স নোশচিনস্কি

14

উইন্ডোজগুলিতে "উইন্ডোজ পাওয়ারশেল" ব্যবহার করে আমি এটি অর্জনের জন্য নীচের বর্ণিত কমান্ডটি ব্যবহার করেছি

Get-Content .\file.txt | Group-Object | Select Name, Count

ফলাফলটি ফিল্টার করতে আমরা যেখানে-অবজেক্ট Cmdlet ব্যবহার করতে পারি

Get-Content .\file.txt | Group-Object | Where-Object { $_.Count -gt 1 } | Select Name, Count

ফাইলের সাজানোর ক্রম পরিবর্তন না করে আপনি শেষটি বাদ দিয়ে ডুপ্লিকেটগুলির সমস্ত উপস্থিতি মুছতে পারবেন?
jparram

6

ধরে নিই যে আপনি একটি স্ট্যান্ডার্ড ইউনিক্স শেল এবং / অথবা সাইগউইন পরিবেশে অ্যাক্সেস পেয়েছেন:

tr -s ' ' '\n' < yourfile | sort | uniq -d -c
       ^--space char

মূলত: সমস্ত স্থানের অক্ষরগুলিকে লাইনব্রেকগুলিতে রূপান্তর করুন, তারপরে ট্রান্সলেস্টেড আউটপুটটি সাজান এবং এটিকে ইউনিক করতে এবং নকল লাইনগুলি গণনা করুন।

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