"Uniq" veya "sort -u" satırım nereye gitti, bazı unicode karakterlerle


10

Aşağıdaki kod snippet'inde neler oluyor? Beklediğim çıktıyı alamıyorum.

Ben bir hata olduğunu düşünürdüm, ama 2 farklı program (uniq ve sort) için olur, bu yüzden bununla ilgili bir şey olduğundan şüpheleniyorum ... şey, ne olduğunu bilmiyorum .. dolayısıyla soru.

İlk 3 (4) örnek işe yarıyor, ancak dördüncü başarısız oluyor.

Tüm karakterler için aynı davranışı beklerdim.
yani. 2 satır yazdırmak için (3 satır girişten) ... ancak 4. durumda, sadece 1 satır alıyorum (hem sort -uve hem de uniq); iki özdeş astar yok oluyor!

Görüntü \ n 'çıktısını kompaktlık için boşluğa dönüştürdüm.

Ben uniq ve sıralama (GNU coreutils) 7.4 ... Ubuntu 10.04.3 LTS masaüstünde çalışan kullanıyorum.

Senaryo:

{
  locale -k LC_COLLATE
  echo
  for c1 in x 〼 ;do 
    for c2 in z 〇 ;do 
      echo -n "asis   : "; echo -e "$c1\n$c2\n$c2"          |tr '\n' ' ';echo
      echo -n "uniq   : "; echo -e "$c1\n$c2\n$c2" |uniq    |tr '\n' ' ';echo
      echo -n "sort -u: "; echo -e "$c1\n$c2\n$c2" |sort -u |tr '\n' ' ';echo
      echo
    done
    echo
  done
}

Çıktı:

collate-nrules=4
collate-rulesets=""
collate-symb-hash-sizemb=2081
collate-codeset="UTF-8"

asis   : x z z 
uniq   : x z 
sort -u: x z 

asis   : x 〇 〇 
uniq   : x 〇 
sort -u: 〇 x 


asis   : 〼 z z 
uniq   : 〼 z 
sort -u: 〼 z 

asis   : 〼 〇 〇 
uniq   : 〼 
sort -u: 〼 

# In the last example (of 4) where did the '〇' go? .. U+3007 IDEOGRAPHIC NUMBER ZERO
#

Lütfen aklınızda bulundurun . sorttek başına ( -u seçeneği olmadan ) ... karakterleri yutmaz .. İçeri girer, çıkar ... Ancak, Gilles'in aynı kanonik değere sahip "egzotik" unicode karakterlerin açıkladığı gibi , bunlar Karakterler, sıralamanın çıktısının "üst" kısmına ayrılmamış bir FIFO grubu olarak çıkarılmaları dışında sıralanmazlar ... Burada gerçekten iki sorun var: 1. Karakterler "safça" olarak sıralanmıyor "beklenen ve 2. Hem" benzersiz "özelliği sortve uniqveri kaybı (bazı durumlarda).
Peter.O

Güncelleme: Gilles tarafından belirtildiği gibi (yerel ayara özel sıralama gerekli olmadığında ve karakter sırası uygun olduğunda) sort -uve uniqşununla iyi çalışın: LC_COLLATE=C; echo -e "〼\n〇\n〇" |sort -u(veya |uniq)
Peter.O

Yanıtlar:


11

Kısa sürüm: harmanlama komut satırı yardımcı programlarında gerçekten çalışmaz.

Daha uzun sürüm: iki dizeyi karşılaştıran temel işlevdir strcoll. Tanım çok yararlı değildir, ancak kavramsal çalışma yöntemi her iki dizeyi kanonik bir forma dönüştürmek ve daha sonra iki kanonik formu karşılaştırmaktır. Fonksiyon strxfrmbu kanonik formu oluşturur.

Birkaç dizenin kanonik biçimlerini gözlemleyelim (GNU libc ile Debian sıkması altında):

$ export LC_ALL=en_US.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' b a A à 〼 〇
b d010801020
a c010801020
A c010801090
à 101010102c6b
〼 101010102c6b102c6b102c6b
〇 101010102c6b102c6b102c6b

Gördüğünüz gibi, 〼 ve 〇 aynı kanonik forma sahiptir. Bence bu karakterler en_US.UTF-8yerel ayarın harmanlama tablolarında belirtilmemiştir . Bununla birlikte, bir Japon yerelinde bulunurlar.

$ export LC_ALL=ja_JP.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' 〼 〇 
〼 303030
〇 3c9b

Yerel veri için kaynak kodu (Debian sıkmada) /usr/share/i18n/locales/en_USiçerir /usr/share/i18n/locales/iso14651_t1_common. Bu dosya için bir giriş yok U3007veya U303Cbulabileceğim herhangi bir aralığa dahil edilmiyorlar .

Harmanlama sırasını oluşturmak için kurallara aşina değilim , ama anladığım kadarıyla ilgili ifade

UNDEFINED sembolü, açıkça belirtilmeyen tüm kodlanmış karakter kümesi değerlerini veya üç nokta simgesi aracılığıyla yorumlanmalıdır. (…) Tanımlanmamış bir simge belirtilmemişse ve geçerli kodlanmış karakter kümesi bu bölümde belirtilmeyen karakterler içeriyorsa, yardımcı program bir uyarı mesajı verir ve bu karakterleri karakter harmanlama sırasının sonuna yerleştirir.

Glibc bunun yerine belirtilmeyen karakterleri yok sayıyor gibi görünüyor. POSIX spesifikasyonunu anlamanın bir kusuru olup olmadığını, Glibc'in yerel tanımında bir şey kaçırdıysam veya Glibc yerel derleyicisinde bir hata olup olmadığını bilmiyorum.


@Gilles: Bilgilendirici ve detaylı açıklama için teşekkürler .. Şimdi bir anlam ifade ediyor, ama merakla bırakıyorum , nasıl "güvenle" sıralama kullanmak .. Ben özellikle "yerel duyarlı" bir tür peşinde değilim, bu yüzden herhangi bir kaba sıralamada ... Bunun hızlı bir çözümü var mı? ... ve yavaş yavaş bunun asılmasını sağlayacağım, ancak 'bir gecede' olmayacak ... örn. / usr / share / i18n / charmaps / UTF-8 , söz konusu her iki karaktere de referans içeriyor , ancak UTF-8 tanımında (?) olmak yardımcı görünmüyor ... Ah, küçük gizemleri olmadan hayat nasıl olurdu. :) ...
Peter.O

1
@fred charmaps/UTF-8harmanlama hakkında hiçbir şey söylemiyor locales/en_US, önemli. İlk kuralı LC_COLLATE: kullanma LC_COLLATE. C (= POSIX) yerel ayarında, harmanlama makuldür (kesinlikle sayısal karakter değerlerine dayanarak).
Gilles 'SO- kötü olmayı kes'

2
Sıralama ve benzersiz önce gelip tarafından boy iyi çalışıyor LC_COLLATE=C... teşekkürler ...
Peter.O

1
Ondan değil harmanlama kamu çalışmaz ama bu glibc yerelleri kötü tasarlanmıştır. Bu davranışa (şu anda, ancak austingroupbugs.net/view.php?id=1070 bakın ) POSIX tarafından izin verildi, ancak talihsiz ve istenmeyen.
Stéphane Chazelas

6

sortUnicode dizelerini "güvenli bir şekilde" düzenlemek için , şunlara bir göz atın msort:

[...] Msort, anahtar alanların seçiminde daha fazla esneklik, daha fazla karşılaştırma türü, farklı tuşlarda farklı yerel ayarlardan gelen harmanlama kurallarını kullanma yeteneği, Batı dışı sayı sistemlerindeki sayıları işleme yeteneği ve eksik olan diğer seçenekleri sunar GNU sıralama ve BSD sıralama. Msort Unicode, GNU sıralama ve BSD sıralama anlamayan anlar. [...]

http://www.billposer.org/Software/msort.html


@til: Beni haberdar ettiğin için teşekkürler msort. İsteğe bağlı GUI, sunulanları hissetmek için tanıtımı biraz daha kolaylaştırır. Oluşturulan komutu kopyalamak çok kullanışlıdır ... Ve evet, unicode karakterleri sıralar, ancak (sadece bu "butları" sevmezsiniz:) ... ama benzersiz bir seçeneği yoktur: (... yayınladığınız bağlantıda belirtildiği gibi: Capabilities of GNU sort and BSD sort lacking in msort are the ability to merge files without sorting them (the --merge option) and the ability to emit only the first of an equal run (the --unique option)... Sıralama olsa çalışıyor :)
Peter.O
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.