आदेश रखते हुए आसन्न डुप्लिकेट लाइनों को हटा दें


11

मेरे पास नामों के साथ एक कॉलम के साथ एक फ़ाइल है जो प्रत्येक बार कई बार दोहराती है। मैं प्रत्येक पुनरावृत्ति को एक में समाहित करना चाहता हूं, जबकि एक ही नाम के किसी भी अन्य दोहराव को बनाए रखना जो उसी नाम के अन्य दोहराव से सटे नहीं हैं।

जैसे मैं बाईं ओर दाईं ओर मुड़ना चाहता हूं:

Golgb1    Golgb1    
Golgb1    Akna
Golgb1    Spata20
Golgb1    Golgb1
Golgb1    Akna
Akna
Akna
Akna
Spata20
Spata20
Spata20
Golgb1
Golgb1
Golgb1
Akna
Akna
Akna

यह वही है जो मैं उपयोग कर रहा हूं: perl -ne 'print if ++$k{$_}==1' file.txt > file2.txt हालांकि, यह विधि केवल बाईं ओर से एक प्रतिनिधि रखती है (यानी गोलब 1 और अकाना दोहराया नहीं जाता है)।

क्या प्रत्येक ब्लॉक के लिए अद्वितीय नाम रखने का एक तरीका है, जबकि कई, गैर-आसन्न ब्लॉकों में दोहराए जाने वाले नाम रखते हैं?

जवाबों:


23

uniq आपके लिए यह करेंगे:

$ uniq inputfile
Golgb1
Akna
Spata20
Golgb1
Akna

2
वाह कि शर्मनाक आसान था! धन्यवाद!
उम्र87

@ आयु87 यूनिक्स महान है! यह केवल इसलिए काम करता है क्योंकि आप डुप्लिकेट को आसन्न होने की उम्मीद करते हैं, पहले से ही (या, गैर-आसन्न लोगों को हटाने की इच्छा नहीं करते हैं)। आम तौर पर, सिफारिश का उपयोग करना हैsort | uniq
jpaugh

1
या अधिक संक्षेप में, sort -u(:
डोपघोटी

9

Awk समाधान:

awk '$1 != name{ print }{ name = $1 }' file.txt

उत्पादन:

Golgb1
Akna
Spata20
Golgb1
Akna

6

इसे आज़माएं - पिछली पंक्ति को सहेजें और वर्तमान लाइन के खिलाफ तुलना करें

$ perl -ne 'print if $p ne $_; $p=$_' ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

आपने टैग uniqकिया है - क्या आपने इसे आज़माया है?

$ uniq ip.txt
Golgb1
Akna
Spata20
Golgb1
Akna

1

सीड के साथ यह निम्नानुसार किया जा सकता है:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

यहाँ हम किसी भी समय 2 लाइनों में पैटर्न स्पेस में हैं। जब उनके बीच की तुलना विफल हो जाती है, तो हम पहले वाले को प्रिंट करते हैं और इसे सामने से काटते हैं और पीछे जाते हैं और अगली पंक्ति को पैटर्न स्पेस में जोड़ते हैं। रिंस ... दोहराने

स्लरल मोड में पर्ल का उपयोग करके हम पूरी फाइल को एक लंबे स्ट्रिंग के रूप में मानते हैं जिस पर रेगेक्स लागू होता है जो आपके लिए तुलना करता है।

perl -0777pe 's//$1/ while /^(.*\n)\1+/gm' input_file

0

राकेश शर्मा के sed समाधान के बारे में प्रश्न

क्या होगा यदि आपके पास एक इनपुट फ़ाइल है जैसे:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.118 48.216
-126.128 48.222
-126.136 48.226

और आप एक आउटपुट फाइल चाहते हैं:

-126.1 48.206
-126.106 48.21
-126.11 48.212
-126.114 48.214
-126.116 48.216
-126.128 48.222
-126.136 48.226

नोट गायब है:

-126.118 48.216

मुझे पता है कि मुझे जो आदेश चाहिए वह आपके समाधान के समान है:

sed -e '$!N;/^\(.*\)\n\1$/!P;D' input_file

दोनों स्तंभों को प्रिंट करने के लिए इसे सही तरीके से बदल नहीं सकता है और केवल कॉलम 2 मानों के साथ इस विशेष तरीके से सॉर्ट किया जाना चाहिए। कोई सुझाव?


sed -e '$!N' -e '/.*\.\([0-9]*\)\n.*\.\1$/!{P;D;}' -e 's/\n.*//;s/^/\n/;D' बाद के दोहराए जाने वाले तत्वों को हटा देगा। नोट: इसकी आवश्यकता है GNU sed। के लिए POSIXव्यवहार में, यह थोड़ा-बहुत बदलाव की जरूरत है।
राकेश शर्मा
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.