কোনও ফাইলের নকল লাইনগুলি মুছে না ফেলে তাদের চিহ্নিত করুন?


11

আমার এন্ট্রিগুলির দীর্ঘ তালিকা সহ একটি পাঠ্য ফাইল হিসাবে আমার রেফারেন্স রয়েছে এবং প্রত্যেকটির দুটি (বা আরও) ক্ষেত্র রয়েছে।

প্রথম কলামটি রেফারেন্সের ইউআরএল; দ্বিতীয় কলামটি শিরোনাম যা এন্ট্রিটি কীভাবে করা হয়েছিল তার উপর নির্ভর করে কিছুটা আলাদা হতে পারে। তৃতীয় ক্ষেত্রের জন্য একই যা উপস্থিত থাকতে পারে বা নাও থাকতে পারে।

আমি প্রথম ক্ষেত্রের (রেফারেন্স ইউআরএল) সাদৃশ্যযুক্ত এন্ট্রিগুলি সনাক্ত করতে চাই তবে তা সরাতে চাই না। আমি জানি sort -k1,1 -uকিন্তু এটি স্বয়ংক্রিয়ভাবে (অ-ইন্টারেক্টিভভাবে) প্রথম হিট বাদে সমস্ত অপসারণ করবে। আমাকে কীভাবে জানার কোনও উপায় আছে যাতে আমি কোনটি ধরে রাখতে পারি তা বেছে নিতে পারি?

একই প্রথম ক্ষেত্র ( http://unix.stackexchange.com/questions/49569/) এর তিনটি রেখার নীচের নির্যাসে , আমি লাইন 2 রাখতে চাই কারণ এতে অতিরিক্ত ট্যাগ রয়েছে (সাজান, সি এল এল) এবং লাইনগুলি # 1 এবং # 3 মুছুন:

http://unix.stackexchange.com/questions/49569/  unique-lines-based-on-the-first-field
http://unix.stackexchange.com/questions/49569/  Unique lines based on the first field   sort, CLI
http://unix.stackexchange.com/questions/49569/  Unique lines based on the first field

এই জাতীয় "সদৃশ" সনাক্ত করতে কোন প্রোগ্রাম আছে কি? তারপরে, আমি ব্যক্তিগতভাবে # 1 এবং # 3 লাইনগুলি মুছে ফেলে নিজেই পরিষ্কার করতে পারি?


আমি আপনার উদাহরণটি পুরোপুরি বুঝতে পারি না ... আপনি কি ইনপুটটির আরও সরল সংস্করণ এবং প্রত্যাশিত আউটপুট দিতে পারবেন?
অলি

দয়া করে দেখুন এখন এটি আরও পরিষ্কার হয় কিনা?
ডিকে বোস

উত্তর:


9

যদি আমি আপনার প্রশ্নটি বুঝতে পারি তবে আমার মনে হয় আপনার এমন কিছু দরকার:

for dup in $(sort -k1,1 -u file.txt | cut -d' ' -f1); do grep -n -- "$dup" file.txt; done

বা:

for dup in $(cut -d " " -f1 file.txt | uniq -d); do grep -n -- "$dup" file.txt; done

file.txtআপনার ফাইল সম্পর্কে আপনার আগ্রহী আগ্রহী where

আউটপুটে আপনি প্রথম ক্ষেত্রটি দুই বা ততোধিক বার পাওয়া গেছে এমন লাইন এবং রেখার সংখ্যা দেখতে পাবেন।


3
আপনাকে ধন্যবাদ: এমনকি cut -d " " -f1 file.txt | uniq -dআমাকে সুন্দর আউটপুট দেয়।
ডিকে বোস

@ ডি কেবোস সম্ভবত আরও অনেক সম্ভাবনা রয়েছে তবে আমি এবং আপনার আদেশটিও ব্যবহার করতে চেয়েছিলাম।
রাদু রেডানু

ধন্যবাদ। দ্বিতীয় আদেশটি আমার পছন্দ মতো one আপনি প্রথমটি মুছে ফেলতে পারেন। এবং আপনি যদি কোডটি ব্যাখ্যা করেন তবে এটিও দুর্দান্ত লাগবে :)
ডি কে বোস

10

এটি একটি শাস্ত্রীয় সমস্যা যা uniqকমান্ড দিয়ে সমাধান করা যেতে পারে । uniqডুপ্লিকেট সনাক্ত করা সম্ভব পরপর (লাইন এবং অপসারণ সদৃশ -u, --unique) অথবা অনুরূপ শুধুমাত্র রাখা ( -d, --repeated)।

যেহেতু সদৃশ লাইনের ক্রম আপনার পক্ষে গুরুত্বপূর্ণ নয়, আপনার প্রথমে এটি বাছাই করা উচিত। তারপরে uniqকেবল অনন্য লাইনগুলি মুদ্রণ করতে ব্যবহার করুন :

sort yourfile.txt | uniq -u

একটি -c( --count) বিকল্প রয়েছে যা বিকল্পটির জন্য সদৃশ সংখ্যা প্রিন্ট করে -duniqবিশদ জন্য ম্যানুয়াল পৃষ্ঠা দেখুন ।


প্রথম ক্ষেত্রের পরে যদি আপনি সত্যিই সেই অংশগুলির বিষয়ে চিন্তা না করেন তবে ডুপ্লিকেট কীগুলি সন্ধান করতে এবং এর জন্য প্রতিটি লাইন নম্বর মুদ্রণ করতে আপনি নিম্নলিখিত কমান্ডটি ব্যবহার করতে পারেন ( | sort -nলাইন অনুসারে আউটপুট সাজানোর জন্য অন্যকে যুক্ত করুন ):

 cut -d ' ' -f1 .bash_history | nl | sort -k2 | uniq -s8 -D

যেহেতু আপনি সদৃশ লাইনগুলি দেখতে চান (প্রথম ক্ষেত্রটি কী হিসাবে ব্যবহার করছেন), আপনি সরাসরি ব্যবহার করতে পারবেন না uniq। অটোমেশনকে জটিল করে তোলে এমন সমস্যাটি শিরোনামের অংশগুলি পৃথক হয় তবে কোনও প্রোগ্রাম স্বয়ংক্রিয়ভাবে নির্ধারণ করতে পারে না যে কোন শিরোনামটিকে চূড়ান্ত হিসাবে বিবেচনা করা উচিত।

এখানে একটি AWK স্ক্রিপ্ট (এতে সংরক্ষণ করুন script.awk) যা আপনার পাঠ্য ফাইলটিকে ইনপুট হিসাবে গ্রহণ করে এবং সমস্ত নকল লাইন প্রিন্ট করে যাতে কোনটি মুছতে হবে তা আপনি সিদ্ধান্ত নিতে পারেন। ( awk -f script.awk yourfile.txt)

#!/usr/bin/awk -f
{
    # Store the line ($0) grouped per URL ($1) with line number (NR) as key
    lines[$1][NR] = $0;
}
END {
    for (url in lines) {
        # find lines that have the URL occur multiple times
        if (length(lines[url]) > 1) {
            for (lineno in lines[url]) {
                # Print duplicate line for decision purposes
                print lines[url][lineno];
                # Alternative: print line number and line
                #print lineno, lines[url][lineno];
            }
        }
    }
}

আমি মনে করি এটি আমি যা চাই তার কাছাকাছি তবে আমার `-f, --skip-Field = N এর বিপরীতে প্রয়োজন (প্রথম এন ক্ষেত্রের সাথে তুলনা করা এড়ানো)। অন্য কথায়, আমি কেবলমাত্র প্রথম ক্ষেত্র, ইউআরএলগুলি বিবেচনা করতে চাই।
ডেকে বোস

@ ডি কেবোস একটি নির্দিষ্ট সংখ্যক অক্ষরের সীমাবদ্ধ করার জন্য একটি -w( --check-chars) বিকল্প রয়েছে, তবে আপনার উদাহরণটি দেখে আপনার চলক প্রথম ক্ষেত্র রয়েছে। যেহেতু uniqক্ষেত্র নির্বাচন সমর্থন করে না, তাই আপনাকে একটি কার্যবিধ ব্যবহার করতে হবে। সহজ যেহেতু আমি AWK উদাহরণ অন্তর্ভুক্ত করব।
লেকেনস্টেইন

হ্যাঁ, আমি কেবল তাকিয়ে ছিলাম -wতবে প্রথম ক্ষেত্রটির দৈর্ঘ্য পরিবর্তনশীল :(
ডি কে বোস

@ ডেকেবস দয়া করে সর্বশেষ সম্পাদনাটি দেখুন
লেকেনস্টেইন

1
আমি বিশ্রী: স্ক্রিপ্ট.ওক: লাইন 4: এর কাছাকাছি বা কাছাকাছি সিনট্যাক্স ত্রুটি করছি [awk: স্ক্রিপ্ট.উক: লাইন 10: কাছাকাছি বা নিকটে [বাকী: স্ক্রিপ্ট.ওক: লাইন 18: সিনট্যাক্স ত্রুটি বা near
ডেকে বোস

2

আমি যদি এটি সঠিকভাবে পড়ে থাকি তবে আপনার প্রয়োজন এমন কিছু

awk '{print $1}' file | sort | uniq -c | 
    while read num dupe; do [[ $num > 1 ]] && grep -n -- "$dupe" file; done

এটি ডুপ এবং লাইন নিজেই থাকা লাইনের সংখ্যা মুদ্রণ করবে। উদাহরণস্বরূপ, এই ফাইলটি ব্যবহার করে:

foo bar baz
http://unix.stackexchange.com/questions/49569/  unique-lines-based-on-the-first-field
bar foo baz
http://unix.stackexchange.com/questions/49569/  Unique lines based on the first field   sort, CLI
baz foo bar
http://unix.stackexchange.com/questions/49569/  Unique lines based on the first field

এটি এই আউটপুট উত্পাদন করবে:

2:http://unix.stackexchange.com/questions/49569/  unique-lines-based-on-the-first-field
4:http://unix.stackexchange.com/questions/49569/  Unique lines based on the first field   sort, CLI
6:http://unix.stackexchange.com/questions/49569/  Unique lines based on the first field

কেবলমাত্র লাইনের সংখ্যা মুদ্রণ করতে, আপনি করতে পারেন

awk '{print $1}' file | sort | uniq -c | 
 while read num dupe; do [[ $num > 1 ]] && grep -n -- "$dupe" file; done | cut -d: -f 1

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

awk '{print $1}' file | sort | uniq -c | 
while read num dupe; do [[ $num > 1 ]] && grep -n -- "$dupe" file; done | cut -d: -f 2-

ব্যাখ্যা:

awkস্ক্রিপ্ট শুধু ছাপে 1 ম স্থান ফাইলের ক্ষেত্র পৃথক করা হয়। $NNth ফিল্ড মুদ্রণ করতে ব্যবহার করুন । sortএটি বাছাই করে এবং uniq -cপ্রতিটি লাইনের উপস্থিতি গণনা করে।

এরপরে এটি লুপটিতে পৌঁছে যায় whileযা সংঘটন সংখ্যা $numএবং রেখার হিসাবে $dupeএবং যদি $numএকের বেশি হয় তবে -nএটি লাইন নম্বরটি মুদ্রণ করে সেই লাইনের জন্য ফাইলটি অনুসন্ধান করবে । আমাদের --জানায় grepযে এরপরে যা কমান্ড লাইন বিকল্প নয় এটি কখন থেকে $dupeশুরু করতে পারে তার জন্য কার্যকর -


1

কোনও সন্দেহ নেই যে তালিকার সবচেয়ে ভার্জোজ এক সম্ভবত সম্ভবত খাটো হতে পারে:

#!/usr/bin/python3
import collections
file = "file.txt"

def find_duplicates(file):
    with open(file, "r") as sourcefile:
        data = sourcefile.readlines()
    splitlines = [
        (index, data[index].split("  ")) for index in range(0, len(data))
        ]
    lineheaders = [item[1][0] for item in splitlines]
    dups = [x for x, y in collections.Counter(lineheaders).items() if y > 1]
    dupsdata = []
    for item in dups:
        occurrences = [
            splitlines_item[0] for splitlines_item in splitlines\
                       if splitlines_item[1][0] == item
            ]
        corresponding_lines = [
            "["+str(index)+"] "+data[index] for index in occurrences
            ]
        dupsdata.append((occurrences, corresponding_lines))

    # printing output   
    print("found duplicates:\n"+"-"*17)
    for index in range(0, len(dups)):
        print(dups[index], dupsdata[index][0])
        lines = [item for item in dupsdata[index][1]]
        for line in lines:
            print(line, end = "")


find_duplicates(file)

একটি পাঠ্য ফাইল যেমন দেয়:

monkey  banana
dog  bone
monkey  banana peanut
cat  mice
dog  cowmeat

যেমন একটি আউটপুট:

found duplicates:
-----------------
dog [1, 4]
[1] dog  bone
[4] dog  cowmeat
monkey [0, 2]
[0] monkey  banana
[2] monkey  banana peanut

একবার আপনি সরানোর জন্য লাইনগুলি বাছাই:

removelist = [2,1]

def remove_duplicates(file, removelist):
    removelist = sorted(removelist, reverse=True)
    with open(file, "r") as sourcefile:
        data = sourcefile.readlines()
    for index in removelist:
        data.pop(index)
    with open(file, "wt") as sourcefile:
        for line in data:
            sourcefile.write(line)

remove_duplicates(file, removelist)

0

নিম্নলিখিত বাছাই করা দেখুন file.txt:

addons.mozilla.org/en-US/firefox/addon/click-to-play-per-element/ ::: C2P per-element
addons.mozilla.org/en-us/firefox/addon/prospector-oneLiner/ ::: OneLiner
askubuntu.com/q/21033 ::: What is the difference between gksudo and gksu?
askubuntu.com/q/21148 ::: openoffice calc sheet tabs (also askubuntu.com/q/138623)
askubuntu.com/q/50540 ::: What is Ubuntu's Definition of a "Registered Application"?
askubuntu.com/q/53762 ::: How to use lm-sensors?
askubuntu.com/q/53762 ::: how-to-use-to-use-lm-sensors
stackoverflow.com/q/4594319 ::: bash - shell replace cr\lf by comma
stackoverflow.com/q/4594319 ::: shell replace cr\lf by comma
wiki.ubuntu.com/ClipboardPersistence ::: ClipboardPersistence
wiki.ubuntu.com/ClipboardPersistence ::: ClipboardPersistence - Ubuntu Wiki
www.youtube.com/watch?v=1olY5Qzmbk8 ::: Create new mime types in Ubuntu
www.youtube.com/watch?v=2hu9JrdSXB8 ::: Change mouse cursor
www.youtube.com/watch?v=Yxfa2fXJ1Wc ::: Mouse cursor size

তালিকাটি সংক্ষিপ্ত হওয়ার কারণে, আমি দেখতে পাচ্ছি (বাছাই করার পরে) নকলের তিন সেট রয়েছে।

তারপরে, উদাহরণস্বরূপ, আমি রাখার জন্য চয়ন করতে পারি:

askubuntu.com/q/53762 ::: How to use lm-sensors?

বরং

askubuntu.com/q/53762 ::: how-to-use-to-use-lm-sensors

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

$ cut -d " " -f1 file.txt | uniq -d
askubuntu.com/q/53762
stackoverflow.com/q/4594319
wiki.ubuntu.com/ClipboardPersistence
$

আমি আমার উত্তরটি আরও একটি বৈকল্পিকের সাথে আপডেট করেছি cut। আপনি যদি ডি-সদৃশ কাজ করছেন, তবে লাইন নম্বরগুলি খুব সহায়ক হতে পারে। সমস্ত অনুলিপি মুদ্রণ করতে, -Dবিকল্প পরিবর্তে ব্যবহার করুন -d
লেকেনস্টেইন

আমি মনে করি আপনি আরও ভাল ব্যবহার করেছেন: for dup in $(cut -d " " -f1 file.txt | uniq -d); do grep -n $dup file.txt; doneযেমন আমার উত্তরে। এটি আপনার আগ্রহী সম্পর্কে আরও ভাল পূর্বরূপ দেয়।
রাদু রেডানু

0

আমি এটি সমাধান করেছি কীভাবে:

file_with_duplicates:

1,a,c
2,a,d
3,a,e <--duplicate
4,a,t
5,b,k <--duplicate
6,b,l
7,b,s
8,b,j
1,b,l
3,a,d <--duplicate
5,b,l <--duplicate

ফাইলটি 1 এবং 2 কলাম অনুসারে বাছাই করা হয়েছে এবং ছাড়ানো হয়েছে:

sort -t',' -k1,1 -k2,2 -u file_with_duplicates

ফাইলটি কেবল 1 এবং 2 কলাম অনুসারে বাছাই করা হয়েছে:

sort -t',' -k1,1 -k2,2 file_with_duplicates

কেবল তফাতটি দেখান:

diff <(sort -t',' -k1,1 -k2,2 -u file_with_duplicates) <(sort -t',' -k1,1 -k2,2 file_with_duplicates)

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