सॉर्ट क्यों कहता है कि e = ई?


25

ɛ("लैटिन एप्सिलॉन") एक पत्र है जो कुछ अफ्रीकी भाषाओं में उपयोग किया जाता है, आमतौर पर अंग्रेजी "बेड" में स्वर ध्वनि का प्रतिनिधित्व करने के लिए। यूनिकोड में यह U + 025B के रूप में कूटबद्ध किया गया है, जो हर रोज से बहुत अलग है e

हालांकि, अगर मैं sortनिम्नलिखित है:

eb
ed
ɛa
ɛc

ऐसा लगता है कि sortसमझता है ɛऔर eसमकक्ष:

ɛa
eb
ɛc
ed

यहाँ क्या चल रहा है? और वहाँ बनाने के लिए एक तरीका है ɛऔर आईएनजी प्रयोजनों के eलिए अलग sortहै?


21
छंटनी के नियमों को '
कोलाजेशन

1
एक पाठ फ़ाइल के eaसाथ मिश्रित की एक निश्चित संख्या डालने की कोशिश करें ɛaऔर इसे सॉर्ट करें। आप देखेंगे कि यह हमेशा eaपहले की तरह है ɛa। तो, नहीं, उन्हें समान नहीं माना जाता है।
बकुरीउ

एक स्पष्ट बिंदु हो सकता है, लेकिन मैंने इसे अभी तक स्पष्ट रूप से सुझाया नहीं देखा है: यदि आप $ में शब्दों को छांट रहे हैं (निश्चित_फ्रीकन_लंगेज), तो करने के लिए प्राकृतिक चीज़ $ (निश्चित_फ्रीकान_लंगेज) तय कर रही है।
फेडेरिको पोलोनी

@FedericoPoloni एक बहुत अच्छी बात! दुर्भाग्य से मैं इस भाषा के लिए बनाए गए किसी भी स्थान को खोजने में सक्षम नहीं हूं।
ड्रेकोनिस

1
@ जर्मेनबॉज यह विशेष रूप से "लैटिन एप्सिलॉन" है, जो लैटिन वर्णमाला के साथ फिट होने के लिए डिज़ाइन किया गया एक रूप है। वे बहुत समान दिखते हैं, लेकिन लैटिन एप्सिलॉन U + 025B है, जबकि ग्रीक एप्सिलॉन U + 03B5 है।
ड्रेकोनिस

जवाबों:


67

नहीं, यह उन्हें समतुल्य नहीं मानता है, उनका बस एक ही प्राथमिक वजन है। ताकि, पहले सन्निकटन में, वे एक ही क्रमबद्ध करें।

यदि आप एक GNU प्रणाली (यहाँ glibc 2.27 के साथ) पर / usr / share / i18n / locates / iso14651_t1_common (अधिकांश स्थानों के आधार के रूप में उपयोग किया जाता है) को देखते हैं, तो आप देखेंगे:

<U0065> <e>;<BAS>;<MIN>;IGNORE # 259 e
<U025B> <e>;<PCL>;<MIN>;IGNORE # 287 ɛ
<U0045> <e>;<BAS>;<CAP>;IGNORE # 577 E

e, ɛऔर Eएक ही प्राथमिक वजन है, eऔर Eएक ही माध्यमिक वजन है, केवल तीसरा वजन उन्हें अलग करता है।

स्ट्रिंग्स की तुलना करते समय, sort( strcoll()स्टैण्डर्ड की तुलना करने के लिए स्टैण्डर्ड लिबास फंक्शन का उपयोग किया जाता है) सभी वर्णों के प्राथमिक वज़न की तुलना करके शुरू होता है, और केवल दूसरे वज़न के लिए जाना जाता है यदि स्ट्रिंग्स प्राइमरी वेट के बराबर हैं (और इसी तरह दूसरे वेट के साथ) ।

ऐसा लगता है कि पहले सन्निकटन में छंटनी क्रम में मामले को नजरअंदाज किया गया है। Abके बीच में aaऔर ac, लेकिन भाषा के नियम के आधार पर Abया उससे पहले सॉर्ट कर सकते abहैं (कुछ भाषाएँ ब्रिटिश अंग्रेजी में <MIN>पहले की <CAP>तरह हैं, कुछ एस्टोनियाई की तरह <CAP>पहले <MIN>)।

यदि eएक ही क्रमबद्ध क्रम होता ɛ, printf '%s\n' e ɛ | sort -uतो केवल एक ही लाइन वापस आती। लेकिन <BAS>पहले की तरह <PCL>, eअकेले पहले की तरह ɛeɛeइसके बाद EEE(द्वितीयक भार पर) भले ही EEEबाद में eee(जिसके लिए हमें तीसरे वजन तक जाने की आवश्यकता है)।

अब अगर मेरे सिस्टम पर glibc 2.27 है, तो मैं चलाता हूं:

sed -n 's/\(.*;[^[:blank:]]*\).*/\1/p' /usr/share/i18n/locales/iso14651_t1_common |
  sort -k2 | uniq -Df1

आप देखेंगे कि कुछ अक्षर ऐसे हैं जिन्हें ठीक उसी 4 वज़न के साथ परिभाषित किया गया है। विशेष रूप से, हमारे particular में समान वजन है:

<U01DD> <e>;<PCL>;<MIN>;IGNORE
<U0259> <e>;<PCL>;<MIN>;IGNORE
<U025B> <e>;<PCL>;<MIN>;IGNORE

और निश्चित रूप से पर्याप्त:

$ printf '%s\n' $'\u01DD' $'\u0259' $'\u025B' | sort -u
ǝ
$ expr ɛ = ǝ
1

इसे GNU libc स्थानों के बग के रूप में देखा जा सकता है। अधिकांश अन्य प्रणालियों पर, स्थान सुनिश्चित करते हैं कि सभी अलग-अलग वर्णों के अंत में अलग-अलग क्रमबद्ध क्रम होते हैं। जीएनयू स्थानों पर, यह, और भी बदतर हो जाता है के रूप में वहाँ अक्षर हैं जो एक छँटाई आदेश की जरूरत नहीं है और एक ही छँटाई अंत के हजारों रहे हैं, (तोड़ने जैसी समस्याओं के सभी प्रकार के कारण comm, join, lsया गैर नियतात्मक आदेश होने globs ... ), इसलिए उन मुद्दों के आसपास काम करने के लिए उपयोग LC_ALL=Cकरने की सिफारिश की गई है ।

जैसा कि @ninjalj द्वारा टिप्पणियों में उल्लेख किया गया है, अगस्त 2018 में जारी 2.28 glibc उस मोर्चे पर कुछ सुधार के साथ आया था हालांकि AFAICS, अभी भी कुछ अक्षर या समान तत्वों को समान क्रमबद्धता के साथ परिभाषित किया गया है। Ubuntu 18.10 पर glibc 2.28 के साथ और एक en_GB.UTF-8 लोकेल में।

$ expr $'L\ub7' = $'L\u387'
1

(क्यों U + 00B7 को U + 0387 के बराबर माना जाएगा जब L/ l!) के साथ जोड़ा जाएगा ।

तथा:

$ perl -lC -e 'for($i=0; $i<0x110000; $i++) {$i = 0xe000 if $i == 0xd800; print chr($i)}' | sort > all-chars-sorted
$ uniq -d all-chars-sorted | wc -l
4
$ uniq -D all-chars-sorted | wc -l
1061355

(अभी भी 1 मिलियन से अधिक वर्ण (यूनिकोड श्रेणी का 95%, 2.27 में 98% से नीचे) अन्य वर्णों की तरह ही छंटनी करते हैं क्योंकि उनका क्रम क्रम परिभाषित नहीं है)।

यह भी देखें:


3
यही वह है जिसकी तलाश में मैं हूं! पूर्णता के लिए, क्या <PCL>खड़ा है? दूसरों को कैपिटल, मिनिस्क्यूल और बेसिक लगता है?
ड्रेकोनिस

3
@ डॉर्कोनिस, कोलेटिंग -सिंबल <PCL> # 16
पार्टिकलियर

दरअसल अगर हम एक गुच्छा डालते हैं eaऔर ɛaएक फाइल में एक साथ मिलाते हैं, तो हम देखते हैं कि एस से पहले sortसभी प्रकार । eaɛa
बाकुरू


1
@cat, माफ करना, मेरा मतलब था strcoll(), संपादित देखें।
स्टीफन चेजलस

15

आदमी की तरह:

   ***  WARNING  ***  The locale specified by the environment affects sort
   order.  Set LC_ALL=C to get the traditional sort order that uses native
   byte values.

इसलिए कोशिश करें: LC_ALL=C sort file.txt


1
यह काम करता है! लेकिन डिफ़ॉल्ट लोकेल इन पूरी तरह से अलग कोडपॉइंट्स को समान क्यों मानता है? मैं उत्सुक हूं कि ऐसा क्यों होता है।
ड्रेकोनिस

@Draconis "डिफ़ॉल्ट लोकेल" क्या है?
कामिल मैकियोरोस्की

@KamilMaciorowski पर्यावरण चर का एक खाली मूल्य; मुझे यकीन नहीं है कि किस लोकेल से मेल खाता है
ड्रेकोनिस

3
अगर LC_ALLखाली है, तो @ चर sortअन्य LC_*चर LANGया कुछ विन्यास फाइल का उपयोग कर सकते हैं ।
निएडजेककोब

1
LC_COLLATEस्ट्रिंग-सॉर्ट-विशिष्ट एक LANGहै, अतिरिक्त-सामान्य एक है।
शैडो रेंजर

8

चरित्र e ई के बराबर नहीं है, लेकिन कुछ स्थान इन संकेतों को एक साथ टकराव पर इकट्ठा कर सकते हैं। इसका कारण भाषा विशिष्ट है, लेकिन कुछ ऐतिहासिक या राजनीतिक पृष्ठभूमि भी है। उदाहरण के लिए, ज्यादातर लोग शायद यह उम्मीद करते हैं कि € uro मुद्रा शब्दकोश में यूरोप के करीब आए ।

वैसे भी यह देखने के लिए कि आप वर्तमान में रन का उपयोग क्या कर रहे हैं locale, यह locale -aआपको सिस्टम पर उपलब्ध स्थानों की सूची देगा और Cकेवल एक छँटाई चलाने के लिए कोलाज को बदलने के लिए कहेगा LC_COLLATE=C sort file। अंत में यह देखने के लिए कि विभिन्न स्थान आपकी फ़ाइल को कैसे सॉर्ट कर सकते हैं

for loc in $(locale -a)
    do echo ____"${loc}"____
    LC_COLLATE="$loc" sort file
done

अपनी जरूरत के अनुसार स्थान चुनने के लिए कुछ ग्रीपिंग टूल के परिणाम को पाइप करें।


यह एक अद्भुत व्याख्या है, लेकिन प्रतीकों को समान माना जाता है, न कि केवल एक साथ करीब।
ड्रेकिन

1
नहीं, वे समान नहीं माने जाते हैं। एक सादे जोड़े eaफाइल करने के लिए लाइन है, तो साथ sort -uआप दोनों मिल जाएगा eaऔर ɛaउत्पादन में। सबसे अच्छी रणनीति बनाम टकराव टालना ( export LC_COLLATE=C) है। अन्यथा, कई बदसूरत चीज़ें होंगी (जैसे। /tmp/[a-z]में bashकी भरपाई कर देंगे /tmp/aऔर /tmp/Aनहीं बल्कि /tmp/Z)।
मॉसवी

@mosvy हुह, दिलचस्प ... इसलिए उन्हें उद्देश्यों को पूरा करने के लिए समान माना जाता है लेकिन विशिष्टता उद्देश्यों के लिए नहीं?
ड्रेकनिस

उन्हें समान नहीं माना जाता है। यहाँ इसके बारे में एक स्पष्टीकरण देखें ।
मॉसवी

1
@njjjj, कि glibc fnmatch()और regexp पर्वतमाला में तय किया जा सकता है , लेकिन कुछ में ऐसा नहीं है bashकि अपनी सीमाओं का उपयोग करके स्वयं को लागू करें strcoll()। ksh93 को कभी समस्या नहीं हुई क्योंकि इसके रेंज कार्यान्वयन का उपयोग करता है strcoll()और रेंज सिरों के मामले की भी जांच करता है और केवल लोअरकेस वर्णों पर मेल खाता है यदि दोनों सिरों पर लोअर केस है। zsh पर्वतमाला में समस्या नहीं है क्योंकि यह कोड बिंदु के आधार पर किया गया है, strcoll () नहीं।
स्टीफन चेज़लस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.