Sıralama neden alfasayısal olmayan karakterleri yok sayıyor?


25

Dosya adlarını sıralarken, lsgibi karakterleri yoksayar -,_. Bu karakterleri de sıralamada kullanmasını bekliyordum.

Bir örnek:

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

Şimdi bu dosyaları şununla göster ls -1:

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

Beklediğim şey şunun gibi bir şeydi:

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

Yani, alfasayısal olmayan karakterlerin sıralama sırasında dikkate alınmasını beklerdim.

Birisi bu davranışı açıklayabilir mi? Bu davranış standart tarafından zorunlu mu? Yoksa bu kodlamanın UTF-8 olması nedeniyle mi?

Güncelleme: Bunun UTF-8 sıralama ile ilgili olduğu görülüyor:

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

2
UTF-8 ve ASCII, kullandığınız tüm ilk 128 kod noktasıysa (örneğinizin olduğu gibi) aynıdır. Eğer yaparsan ne olur LC_COLLATE=C ls?
Alexios

Sorun ASCII ve UTF-8'in aynı olmaması, UTF-8'in kendi harmanlama (sıralama) kurallarına sahip olması değil.
daniel kullmann

1
Evet, [_-,.]gruplandırılmış ve bir şekilde yarı ihmal edilmiş olduğu doğrudur . Basitçe ve sadece, için harmanlama değiştirme çünkü ben böyle harmanlama tanımlanır tam olarak nasıl ve nerede bilmiyorum, ama bir harmanlama sorunu olmalı C (aracılığıyla LC_COLLATE=C ls -l) varsayarak (size beklenen sıralama düzeni vermek için yeterlidir LC_ALLolduğunu geçersiz kılma değil LC_COLLATE). Bu, Unicode Temel Çok Dilli
Düzlem'deki

nasıl çalıştığını beğenmiyorsanız, bir takma ad oluşturabilir ve ~ / .profile'inize koyabilirsiniz: alias ls = 'LC_COLLATE = C ls' </kbd>
jippie

Yanıtlar:


10

Bunun karakter seti ile ilgisi yok. Aksine, harmanlama sırasını belirleyen dildir. Libc, $LC_COLLATE/ $LC_ALL/ 'da sunulan dili inceler $LANGve harmanlama kurallarını arar (örn /usr/share/i18n/locales/*. GLibC için) ve metni yönlendirildiği şekilde sıralar.


Bilginize: Bundan daha karmaşık. strcollÖrneğin, biri kullanılacaksa , bunun gibi bir şeyin aasa.cyukarıda sıralanacağını göreceksiniz aas.c.
Don Scott,

12

EDIT: LC_COLLATE = C ile sıralanmış veriler için test eklendi


Varsayılan harmanlama sırası, bu "noktalama tipi" karakterleri eşit değerde olarak kabul Use LC_COLLATE=Ceder.

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

Çıktı

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

Aşağıdaki kod , Temel Çok Dilli Düzlem'deki tüm geçerli UTF-8 karakterlerini test eder ( basitlik için \ x00 ve \ x0a hariç )
Bir dosyayı, bilinen (oluşturulan) artan bir sırada, rasgele olarak sıralanan ve daha sonra tekrar sıralanan şekilde karşılaştırır. LC_COLLATE = C. Sonuç, C dizisinin orijinal üretilen dizilim ile aynı olduğunu göstermektedir .

{ 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 $?='$?

Çıktı:

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

cmp $?=0

2
Bu nerede belgelenmiştir? Unicode standardının bir parçası mı?
daniel kullmann

2
Aslında, aynı değeri alamazlar; sıralama sırasında bu karakterler basit bir şekilde yoksayılır. Eşit bir değere sahip oldukları kabul edilirse, sıralama düzeni a_1 a2 a_2imkansız olurdu.
daniel kullmann

Sıkı çalışma ve örnek kod için +1. Dizin adlarını noktalama işaretleriyle aynı şekilde sıralamak saatler geçtikten sonra, noktalama treeişaretlerinin karşılaştırma dizgilerinden kaldırılması veya bunun gibi bir şey gibi daha fazla olduğunu düşünüyorum. /Karakterin harmanlama sırasındaki en düşük karakter olarak ayarlanması gerektiğini söyleyebilirim .
WinEunuuchs2Unix
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.