"सॉर्ट -यू" और "सॉर्ट" में क्या अंतर है uniq "?


119

हर जगह मुझे लगता है कि किसी को क्रमबद्ध, अद्वितीय सूची प्राप्त करने की आवश्यकता है, वे हमेशा पाइप करते हैं sort | uniq। मैंने कभी कोई उदाहरण नहीं देखा है जहां कोई sort -uइसके बजाय उपयोग करता है । क्यों नहीं? क्या अंतर है, और यूनीक को छांटने के लिए यूनीक का उपयोग करना बेहतर क्यों है?


जवाबों:


119

sort | uniqपहले मौजूद था sort -u, और सिस्टम की एक विस्तृत श्रृंखला के साथ संगत है, हालांकि लगभग सभी आधुनिक सिस्टम समर्थन करते हैं -u- यह पॉसिक्स है। यह ज्यादातर उन दिनों के लिए होता है जब sort -uअस्तित्व में नहीं था (और लोग अपने तरीकों को बदलने के लिए नहीं जाते हैं अगर उन्हें पता है कि जिस तरह से काम करना जारी है, बस ifconfigबनाम ipअपनाने को देखें)।

इन दोनों का विलय होने की संभावना थी क्योंकि किसी फ़ाइल के भीतर डुप्लिकेट को हटाने के लिए छंटाई की आवश्यकता होती है (कम से कम, मानक मामले में), और सॉर्ट का एक अत्यंत सामान्य उपयोग मामला है। यह आंतरिक रूप से तेजी से एक ही समय में दोनों संचालन करने में सक्षम होने के परिणामस्वरूप (और इस तथ्य के कारण है कि इसके बीच आईपीसी की आवश्यकता नहीं है uniqऔर sort)। खासकर यदि फ़ाइल बड़ी है, sort -uतो संभवतः डेटा को सॉर्ट करने के लिए कम मध्यवर्ती फ़ाइलों का उपयोग करेगी।

अपने सिस्टम पर मुझे लगातार इस तरह के परिणाम मिलते हैं:

$ dd if=/dev/urandom of=/dev/shm/file bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 8.95208 s, 11.7 MB/s
$ time sort -u /dev/shm/file >/dev/null

real        0m0.500s
user        0m0.767s
sys         0m0.167s
$ time sort /dev/shm/file | uniq >/dev/null

real        0m0.772s
user        0m1.137s
sys         0m0.273s

यह भी की वापसी कोड मुखौटा नहीं करता sortहै, जो महत्वपूर्ण हो सकता है (आधुनिक गोले में वहाँ तरीके यह प्राप्त करने के लिए, उदाहरण के लिए, कर रहे हैं bashकी $PIPESTATUSसरणी, लेकिन यह हमेशा सच नहीं था)।


31
मैं sort | uniq10 में से 9 बार उपयोग करने के लिए तैयार हूं, मैं वास्तव में पाइपिंग कर रहा हूं uniq -c
प्लूटोर

5
ध्यान दें कि sort -u7 वें संस्करण का हिस्सा था UNIX, लगभग 1979। sortसमर्थन के बिना संस्करण -uवास्तव में पुरातन हैं - या POSIX के de jure मानक से पहले वास्तविक तथ्य पर ध्यान दिए बिना लिखे गए थे। 2010 से लिनक्स खोल में स्टैक ओवरफ्लो सॉर्ट और यूनीक भी देखें ।
जोनाथन लेफ़लर

3
की वजह से +1 ip। यह 2016 है और 2013 में यह पोस्ट है, लेकिन मैं केवल ipअब कमांड के बारे में जानता हूं ।
dieend

4
+1 के लिए "9 बार 10 मैं वास्तव में पाइपिंग कर रहा हूं uniq -c" (और शायद एक बार और पाइपिंग कर रहा हूं sort -nr | head)। मैं सोच रहा था कि sort | uniqविम में बराबर क्या है जब मुझे पता चला कि विम के पास :sort uकमांड है। और टीआईएल भी sort -uमौजूद है।
ज़ूयून वी।

ध्यान दें कि sort -n | uniqबनाम का उपयोग करते समय एक अंतर है sort -n -u। उदाहरण के लिए अनुगामी और प्रमुख व्हाट्सएप को डुप्लिकेट के रूप में देखा जाएगा sort -n -uलेकिन पूर्व द्वारा नहीं! echo -e 'test \n test' | sort -n -uलौटता है test, लेकिन echo -e 'test \n test' | sort -n | uniqदोनों लाइनों को लौटाता है।
mxmlnkn

46

एक अंतर यह है कि uniqकई उपयोगी अतिरिक्त विकल्प हैं, जैसे कि मूल्य के दोहराव की संख्या की तुलना और गणना के लिए फ़ील्ड को छोड़ देना। sortके -uध्वज केवल अनलंकृत की कार्यक्षमता को लागू करता है uniqआदेश।


3
एक उपयोगी उत्तर के लिए +0.49, लेकिन मैं इसे कुछ इस तरह उद्धृत करूंगा " बाद के कुछ उपयोगी विकल्पों का उपयोग sort -uकरने के uniqलिए आउटपुट को पारित नहीं किया जा सकता है , जैसे कि तुलना के लिए फ़ील्ड को छोड़ देना और पुनरावृत्ति की संख्या गिनना।"
l0b0

15
+1 वालों में ऑफसेट करने के लिए "प्रकार से सीधे यह करने के लिए कोई रास्ता नहीं है वहाँ" क्योंकि करता है इस सवाल का जवाब ...
Izkata

42

POSIX अनुरूप sorts और uniqs के साथ (GNU uniqवर्तमान में उस संबंध में आज्ञाकारी नहीं है), इसमें अंतर है कि sortलोकेल के कॉलेटिंग एल्गोरिदम का उपयोग strcoll()स्ट्रिंग्स की तुलना करने के लिए uniqकरता है (आमतौर पर तार की तुलना करने के लिए उपयोग करेगा ) जबकि बाइट-मूल्य पहचान (आमतौर पर उपयोग करेगा strcmp()) के लिए चेक ।

वह कम से कम दो कारणों से मायने रखता है।

  • कुछ स्थानों में, विशेष रूप से जीएनयू सिस्टम पर, अलग-अलग वर्ण हैं जो समान हैं। उदाहरण के लिए, एक GNU सिस्टम पर en_US.UTF-8 लोकेल में, सभी characters ... अक्षर और कई अन्य समान हैं क्योंकि उनका क्रम क्रम परिभाषित नहीं है। 0123456789 अरबी अंक अपने पूर्वी अरबी इंडिक समकक्षों (٠١٢٣٤٥٦٧٨٩) के समान हैं।

    के लिए sort -u, the की तरह ही ② और 0123 के समान है, इसलिए sort -uwould तो प्रत्येक में से केवल एक को बनाए रखेगा, जबकि uniq(GNU uniqका उपयोग नहीं करता है strcoll()(को छोड़कर -i)), ① ② से अलग है और different 0123 से अलग है, इसलिए uniqसभी पर विचार करेंगे 4 अद्वितीय।

  • strcollकेवल वैध वर्णों के तार की तुलना कर सकते हैं (जब इनपुट बाइट्स के अनुक्रम है तो व्यवहार POSIX के अनुसार अपरिभाषित होता है) जो वैध वर्ण नहीं बनाते हैं) जबकि strcmp()वर्णों की परवाह नहीं करता क्योंकि यह केवल बाइट-टू-बाइट तुलना करता है। इसलिए यह एक और कारण है कि sort -uअगर आप उनमें से कुछ मान्य पाठ नहीं बनाते हैं, तो आप सभी अनूठी पंक्तियाँ क्यों नहीं दे सकते हैं। sort|uniq, जबकि गैर-पाठ इनपुट पर अभी भी अनिर्दिष्ट है, व्यवहार में आपको उस कारण के लिए अद्वितीय लाइनें देने की अधिक संभावना है।

उन बारीकियों के अलावा, एक बात है कि अब तक का उल्लेख किया नहीं किया गया है कि uniqपूरे लाइन lexically तुलना, जबकि sortके -uकमांड लाइन पर दी प्रकार विनिर्देशन पर आधारित है।

$ printf '%s\n' 'a b' 'a c' | sort -uk 1,1
a b
$ printf '%s\n' 'a b' 'a c' | sort -k 1,1 | uniq
a b
a c

$ printf '%s\n' 0 -0 +0 00 '' | sort -n | uniq
0
-0
+0
00

$ printf '%s\n' 0 -0 +0 00 '' | sort -nu
0

9

मैं उपयोग करना पसंद करता हूं sort | uniqक्योंकि जब मैं -uमिश्रित केस स्ट्रिंग्स से डुप्लिकेट को हटाने के लिए (डुप्लिकेट को समाप्त) विकल्प का उपयोग करने की कोशिश करता हूं , तो परिणाम को समझना इतना आसान नहीं है।

ध्यान दें: इससे पहले कि आप नीचे दिए गए उदाहरणों को चला सकें, आपको निम्न कार्य करके मानक C कोलेटिंग अनुक्रम को अनुकरण करने की आवश्यकता है:

LC_ALL=C
export LC_ALL

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

$ cat short      #file to sort
Pear
Pear
apple
pear
Apple

$ sort short     #normal sort (in normal C collating sequence)
Apple            #the lower case words are at the end
Pear
Pear
apple
pear

$ sort -f short  #correctly sorts ignoring the C collating order
Apple            #but duplicates are still there
apple
Pear
Pear
pear

$ sort -fu short #By adding the -u option to remove duplicates it is 
apple            #difficult to ascertain the logic that sort uses to remove
Pear             #duplicates(i.e., why did it remove pear instead of Pear?)

यह भ्रम -uडुप्लिकेट को हटाने के विकल्प का उपयोग नहीं करके हल किया गया है । का उपयोग करना uniqअधिक पूर्वानुमान है। नीचे पहला प्रकार है और मामले को अनदेखा करता है और फिर uniqडुप्लिकेट को निकालने के लिए इसे पास करता है ।

$ sort -f short | uniq
Apple
apple
Pear
pear

2
-uसमान रन sortके पहले आउटपुट का विकल्प (मैन पेज देखें)। इस प्रकार sort -fuहर केस-असंवेदनशील अनूठी लाइन की पहली घटना को चुनता है। sortडुप्लिकेट को हटाने के लिए तर्क का उपयोग किया जाता है।
पल्ल्क

3

एक और अंतर जो मुझे आज पता चला वह यह है कि एक परिधि के आधार पर छंटनी जहां sort -uकेवल उस स्तंभ पर अद्वितीय ध्वज को लागू करता है जिसे आप सॉर्ट करते हैं।

$ cat input.csv
3,World,1
1,Hello,1
2,Hello,1

$ cat input.csv | sort -t',' -k2 -u
1,Hello,1
3,World,1

$ cat input.csv | sort -t',' -k2 | uniq
1,Hello,1
2,Hello,1
3,World,1

यह स्टीफन Chazelas से एक जवाब में बताया गया है, लेकिन मैं अपने उदाहरण तो चाहते +1
roaima

@Roaima को इंगित करने के लिए धन्यवाद, यह उस उत्तर में बहुत स्पष्ट नहीं था
स्टीफनोस चर्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.