अनोखी लाइनें छापना


15

sortऔर के संयोजन के अलावा अन्य अनूठी पंक्तियों को मुद्रित करने के लिए कुछ बेहतर समाधान है uniq?


1
"बेहतर" से आपका क्या मतलब है?
गाबा

@gabe को उदाहरण के लिए पूरी फ़ाइल को मेमोरी में स्टोर करने की आवश्यकता नहीं है।
Let_Me_Be

के कुछ संस्करणों sort(जैसे। GNU coreutils) अस्थायी फ़ाइलें और बाहरी mergesort का उपयोग करता है, तो इनपुट रैम में फिट करने के लिए बहुत बड़ा है। और अधिकांश अन्य संस्करणों में एक -mविकल्प होता है, इसलिए यह स्पष्ट रूप से इनपुट को split
चुनकर

जवाबों:


25

किसी भी क्रम में केवल एक समान रेखा प्रिंट करने के लिए:

sort -u

किसी भी क्रम में केवल अद्वितीय रेखाएँ मुद्रित करने के लिए:

sort | uniq -u

प्रत्येक समान लाइन को केवल एक बार प्रिंट करने के लिए, उनकी पहली घटना के क्रम में: (प्रत्येक पंक्ति के लिए, लाइन को प्रिंट करें यदि यह अभी तक नहीं देखा गया है, तो किसी भी स्थिति में देखा गया काउंटर बढ़ाएँ)

awk '!seen[$0] {print}
     {++seen[$0]}'

केवल अपनी पहली घटना के क्रम में, केवल अद्वितीय रेखाएँ मुद्रित करने के लिए: (प्रत्येक पंक्ति को रिकॉर्ड करें seenऔर linesयदि यह पहली घटना है, तो इनपुट के अंत में, घटना के क्रम में लाइनें प्रिंट करें, लेकिन केवल वही देखी जाए एक बार)

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

8
कैसे के बारे में awk '!seen[$0]++ {print}'?
asoundmove

10
या इससे भी कम awk '!seen[$0]++', क्योंकि {print}एक खाली कमांड द्वारा निहित है।
क्वाजर

3

कुछ (सबसे?) संस्करणों में sortएक -uझंडा होता है जो uniqसीधे भाग करता है। कार्यान्वयन के आधार पर कुछ लाइन लंबाई प्रतिबंध हो सकते हैं, लेकिन आपके पास पहले से ही सादे थे sort|uniq


1
एर? sort -uV7 पर कम से कम वापस जाता है।
गीकॉस्टर

हम ... मुझे लगा कि मुझे सोलारिस या एआईएक्स याद है। मैं गलत हूँ, हालांकि, वे दोनों यह है।
मैट

सोलारिस और AIX में -u512-वर्ण लाइन लंबाई प्रतिबंध है। (वास्तव में, मुझे लगता है कि सोलारिस 9 सन के आसपास कहीं यह 5120 पर पहुंच गया। जीएनयू अभी भी जीतता है।)
गीकॉउसर

@geekosaur: क्या आपको यकीन है? जेपी लिंडरमैन, बेल सिस्टम टेक्निकल द्वारा sort थ्योरी एंड प्रैक्टिस इन द कंस्ट्रक्शन ऑफ ए वर्किंग सॉर्ट रूटीन ’में प्रलेखित लाइन-लेंथ पर 512-बाइट की सीमा को हटाने के लिए किया गया कार्य। जर्नल, 63, 1827- 1843 (1984)।
जोनाथन लेफ़लर

0

क्या पर्ल आपके लिए काम करता है? यह लाइनों को मूल क्रम में रख सकता है, भले ही डुप्लिकेट आसन्न न हो। आप इसे पायथन में भी कोड कर सकते हैं, या awk

while (<>) {
    print if $lines{$_}++ == 0;
}

जिसे सिर्फ छोटा किया जा सकता है

perl -ne 'print unless $lines{$_}++;'

दी गई इनपुट फ़ाइल:

abc
def
abc
ghi
abc
def
abc
ghi
jkl

यह उत्पादन प्राप्त करता है:

abc
def
ghi
jkl

$ लाइनों को कहाँ परिभाषित किया जा रहा है?
ग्रीग लेवेंटल

यह नहीं है। के बाद से वहाँ नहीं है एक use strict;या use warnings;(वास्तव में, यह है strictकि यहां सबसे अधिक प्रासंगिक है), वहाँ का उपयोग कर के बारे में कोई शिकायत नहीं है %linesइससे पहले कि यह परिभाषित किया गया है। यदि सख्ती के साथ चलाया जाता है, my %lines;तो लूप से पहले एक लाइन की आवश्यकता होगी । ध्यान दें, भी, हैश है %lines; हैश के एक तत्व को $lines{$_}अंकन का उपयोग करके संदर्भित किया जाता है।
जोनाथन लेफलर

मुझे लगता है कि sortबड़ी मात्रा में डेटा के लिए समाधान बेहतर हो सकता है (ओपी "मेमोरी में संपूर्ण फ़ाइल को संग्रहीत करने" के बारे में चिंतित था)। sortयदि डेटा उपलब्ध मेमोरी से बड़ा है तो आउट-ऑफ-कोर सॉर्ट करेगा।
Kusalananda

0

वर्णित उत्तर के अंतिम भाग के लिए: इस प्रश्न के उत्तर के रूप में @Gilles द्वारा अद्वितीय पंक्तियों को मुद्रित करते हुए, मैंने दो हैश का उपयोग करने की आवश्यकता को समाप्त करने का प्रयास किया।

यह समाधान इस प्रकार है: अपनी पहली घटना के क्रम में केवल अद्वितीय रेखाएँ मुद्रित करने के लिए:

awk '{counter[$0]++} END {for (line in counter) if (counter[line]==1) print line}'

यहां, "काउंटर" प्रत्येक पंक्ति की एक गिनती को संग्रहीत करता है जो पहले संसाधित एक के समान है।
अंत में, हम केवल उन पंक्तियों को प्रिंट करते हैं, जिनका काउंटर मान 1 है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.