गैर-अल्फ़ान्यूमेरिक वर्णों को अनदेखा करने में एलएस क्यों छांटता है?


25

फ़ाइल नामों को सॉर्ट करते समय, lsवर्णों की उपेक्षा करें -,_। मुझे उम्मीद थी कि यह उन पात्रों को भी छाँटने में इस्तेमाल करेगा।

एक उदाहरण:

touch a1 a2 a-1 a-2 a_1 a_2 a.1 a.2 a,1 a,2

अब इन फ़ाइलों को प्रदर्शित करें ls -1:

a1
a_1
a-1
a,1
a.1
a2
a_2
a-2
a,2
a.2

मुझे उम्मीद थी कि कुछ इस तरह से होगा:

a1
a2
a,1
a,2
a.1
a.2
a_1
a_2
a-1
a-2

यानी मुझे उम्मीद थी कि छँटाई करते समय गैर-अल्फ़ान्यूमेरिक वर्णों को ध्यान में रखा जाएगा।

क्या कोई इस व्यवहार की व्याख्या कर सकता है? क्या यह व्यवहार एक मानक द्वारा अनिवार्य है? या क्या यह एन्कोडिंग UTF-8 होने के कारण है?

अद्यतन: ऐसा लगता है कि यह UTF-8 छँटाई से संबंधित है:

$ LC_COLLATE=C ls -1
a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2

2
यूटीएफ -8 और एएससीआईआई समान हैं यदि आप उपयोग कर रहे हैं तो पहले 128 कोडपॉइंट्स (जो आपका उदाहरण है) है। यदि आप करते हैं तो क्या होता है LC_COLLATE=C ls?
एलेक्सिओस

समस्या यह नहीं है कि एएससीआईआई और यूटीएफ -8 समान हैं, बल्कि यह है कि यूटीएफ -8 के अपने कॉलेशन (सॉर्ट) नियम हैं।
डैनियल कुलमन

1
हां, यह सच है कि [_-,.]समूहबद्ध किया जा रहा है और किसी तरह अर्ध-उपेक्षित है। मुझे ठीक से पता नहीं है कि इस तरह के टकराव को कैसे या कहां परिभाषित किया गया है, लेकिन यह एक टकराव का मुद्दा होना चाहिए, क्योंकि बस, और केवल, कोलाज को C (के माध्यम से LC_COLLATE=C ls -l) में बदलना आपको अपेक्षित क्रम देने के लिए पर्याप्त है (मान LC_ALLलेना) ओवरराइडिंग नहीं LC_COLLATE)। यह यूनिकोड बेसिक बहुभाषी विमान में वर्णों की पूरी श्रृंखला के लिए सही है ... मैंने एक उदाहरण स्क्रिप्ट को शामिल करने के लिए अपना उत्तर संपादित किया है जो इसे बाहर करता है ...
पीटर।

यदि आपको यह पसंद नहीं है कि यह कैसे काम करता है, तो आप एक उपनाम बना सकते हैं और इसे अपने ~ / .profile: alias ls = 'LC_COLLATE = C ls' </ kbd>
jippie

जवाबों:


10

इसका चारसेट से कोई लेना-देना नहीं है। बल्कि, यह भाषा है जो टकराव के क्रम को निर्धारित करती है। परिवाद $LC_COLLATE/ $LC_ALL/ में प्रस्तुत भाषा की जांच करता है $LANGऔर इसके /usr/share/i18n/locales/*टकराव के नियमों (जैसे GLibC के लिए) को देखता है और निर्देश के अनुसार पाठ का आदेश देता है।


FYI करें: यह इससे अधिक जटिल है। यदि कोई strcollउदाहरण के लिए उपयोग करता है, तो आप देखेंगे कि ऐसा कुछ aasa.cऊपर छांटा जाएगा aas.c
डॉन स्कॉट

12

EDIT: LC_COLLATE = C के साथ सॉर्ट किए गए डेटा के लिए जोड़ा गया परीक्षण


डिफ़ॉल्ट कोलाट अनुक्रम उन "विराम चिह्न-प्रकार" वर्णों को समान मान Use LC_COLLATE=Cके साथ व्यवहार कर रहा है .. उन्हें कोडपॉइंट क्रम में इलाज करने के लिए ..

for i in 'a1' 'a_1' 'a-1' 'a,1' 'a.1' 'a2' 'a_2' 'a-2' 'a,2' 'a.2' ;do
  echo $i; 
done |LC_COLLATE=C sort

उत्पादन

a,1
a,2
a-1
a-2
a.1
a.2
a1
a2
a_1
a_2

निम्न कोड बेसिक बहुभाषी विमान ( सादगी के लिए \ x00 और x0a को छोड़कर) में सभी वैध UTF-8 वर्णों का परीक्षण करता है , यह एक ज्ञात (उत्पन्न) आरोही अनुक्रम में एक फ़ाइल की तुलना करता है, उस फ़ाइल के खिलाफ क्रमबद्ध रूप से सॉर्ट किया गया और उसके बाद फिर से सॉर्ट किया गया LC_COLLATE = सी। परिणाम दिखाता है कि सी अनुक्रम मूल उत्पन्न अनुक्रम के समान है।

{ i=0 j=0 k=0 l=0
  for i in {0..9} {A..F} ;do
  for j in {0..9} {A..F} ;do
  for k in {0..9} {A..F} ;do
  for l in {0..9} {A..F} ;do
     (( 16#$i$j$k$l == 16#0000 )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l == 16#000A )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l >= 16#D800    && 
        16#$i$j$k$l <= 16#DFFF )) && { printf '.' >&2; continue; }
     (( 16#$i$j$k$l >= 16#FFFE )) && { printf '.' >&2; continue; }
     echo 0x"$i$j$k$l" |recode UTF-16BE/x4..UTF-8 || { echo "ERROR at codepoint $i$j$k$l " >&2; continue; } 
     echo 
  done
  done
  done; echo -n "$i$j$k$l " >&2
  done; echo >&2
} >listGen

             sort -R listGen    > listRandom
LC_COLLATE=C sort    listRandom > listCsort 

diff <(cat listGen;   echo "last line of listOrig " ) \
     <(cat listCsort; echo "last line of listCsort" )
echo 
cmp listGen listCsort; echo 'cmp $?='$?

आउटपुट:

63485c63485
< last line of listOrig 
---
> last line of listCsort

cmp $?=0

2
वह दस्तावेज कहां है? क्या यह यूनिकोड मानक का हिस्सा है?
डेनियल कुल्मन 10

2
वास्तव में, उन्हें समान मूल्य नहीं मिलता है; छांटने पर उन पात्रों को बस नजरअंदाज कर दिया जाता है। यदि उन्हें एक समान मूल्य माना जाता है, तो क्रमबद्धता a_1 a2 a_2असंभव होगी।
डेनियल कुल्मन 10

अपनी मेहनत और नमूना कोड के लिए +1। कई घंटों के बाद निर्देशिका के नामों को छांटने के साथ विराम चिह्न जिस तरह से treeलगता है कि मुझे लगता है कि कहानी में कुछ और है जैसे विराम चिह्न को तुलना के तार से हटाया जा रहा है या ऐसा कुछ। मैं कह सकता हूं कि /चरित्र को कोलाटिंग सीक्वेंस में सबसे कम चरित्र के रूप में सेट किया जाना चाहिए, इससे कोई फर्क नहीं पड़ता।
WinEunuuchs2Unix
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.