Que se passe-t-il dans l'extrait de code suivant? Je n'obtiens pas la sortie attendue.
Je pense que c'était un bug, mais cela arrive pour 2 programmes différents (uniq et sort), donc je soupçonne que c'est quelque chose à voir avec ... eh bien, je ne sais pas quoi ... d'où la question.
Les 3 premiers (sur 4) exemples fonctionnent, mais le 4ème échoue!.
Je m'attendrais au même comportement pour tous les personnages.
c'est à dire. pour imprimer 2 lignes (à partir des 3 lignes d'entrée) ... mais dans le 4ème cas, je n'ai qu'une ligne (pour les deux sort -u
et uniq
); les deux lins identiques disparaissent!
J'ai converti la sortie '\ n' en espace pour la compacité de la vue.
J'utilise uniq et je trie depuis (GNU coreutils) 7.4 ... fonctionnant sur le bureau Ubuntu 10.04.3 LTS.
Le scénario:
{
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
}
Le résultat:
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
#
sort
seul (sans l' option -u ) ... ne gobe pas les caractères .. Ce qui entre, sort ... Cependant, comme on peut s'y attendre en expliquant Gilles des caractères unicodes "exotiques" ayant la même valeur canonique , ceux-ci les caractères ne sont pas triés, à part le fait qu'ils sont sortis en tant que groupe FIFO non trié en "haut" de la sortie du tri ... Il y a donc vraiment deux problèmes ici: 1. Les caractères ne sont pas triés comme ils le seraient "naïvement" "attendu, et 2. La caractéristique" unique "des deuxsort
et deuniq
perdre des données (dans certains cas).sort -u
etuniq
fonctionneLC_COLLATE=C; echo -e "〼\n〇\n〇" |sort -u
|uniq
Réponses:
Version courte: le classement ne fonctionne pas vraiment dans les utilitaires de ligne de commande.
Version plus longue: la fonction sous-jacente pour comparer deux chaînes est
strcoll
. La description n'est pas très utile, mais la méthode conceptuelle de fonctionnement consiste à convertir les deux chaînes en une forme canonique, puis à comparer les deux formes canoniques. La fonctionstrxfrm
construit cette forme canonique.Observons les formes canoniques de quelques chaînes (avec GNU libc, sous Debian squeeze):
Comme vous pouvez le voir, 〼 et 〇 ont la même forme canonique. Je pense que c'est parce que ces caractères ne sont pas mentionnés dans les tables de classement des
en_US.UTF-8
paramètres régionaux. Ils sont cependant présents dans un lieu japonais.Le code source des données locales (dans Debian Squeeze) est dans
/usr/share/i18n/locales/en_US
, ce qui inclut/usr/share/i18n/locales/iso14651_t1_common
. Ce fichier n'a pas d'entrée pourU3007
ouU303C
, et ils ne sont inclus dans aucune plage que je puisse trouver.Je ne connais pas les règles pour construire l'ordre de classement , mais d'après ce que je comprends, la formulation pertinente est
Il semble que Glibc ignore les caractères qui ne sont pas spécifiés. Je ne sais pas s'il y a une faille dans ma compréhension de la spécification POSIX, si j'ai raté quelque chose dans la définition des paramètres régionaux de Glibc ou s'il y a un bogue dans le compilateur de paramètres régionaux de Glibc.
la source
charmaps/UTF-8
ne dit rien sur le classement, c'est celocales/en_US
qui compte. La première règleLC_COLLATE
est: ne pas utiliserLC_COLLATE
. Dans les paramètres régionaux C (= POSIX), le classement est raisonnable (basé strictement sur des valeurs de caractères numériques).LC_COLLATE=C
... merci ...Pour "en toute sécurité" les
sort
chaînes Unicode, jetez un œil àmsort
:http://www.billposer.org/Software/msort.html
la source
msort
. L'interface graphique en option rend l'introduction un peu plus facile pour avoir une idée de ce qui est proposé. Pouvoir copier la commande générée est très pratique ... Et oui, il trie les caractères unicode, mais (n'aimez-vous pas simplement ces "mais":) ... mais il n'a pas d' option unique : (... comme mentionné sur le lien que vous avez publié: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)
... Le tri fonctionne