Versão resumida: o agrupamento realmente não funciona nos utilitários de linha de comando.
Versão mais longa: a função subjacente para comparar duas sequências é strcoll
. A descrição não é muito útil, mas o método conceitual de operação é converter as duas cadeias em uma forma canônica e, em seguida, comparar as duas formas canônicas. A função strxfrm
constrói essa forma canônica.
Vamos observar as formas canônicas de algumas strings (com o GNU libc, sob o Debian squeeze):
$ 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
Como você pode ver, 〼 e 〇 têm a mesma forma canônica. Eu acho que é porque esses caracteres não são mencionados nas tabelas de agrupamento do en_US.UTF-8
locale. Eles estão, no entanto, presentes em uma localidade japonesa.
$ export LC_ALL=ja_JP.UTF-8
$ perl -C255 -MPOSIX -le 'print "$_ ", unpack("h*", strxfrm($_)) foreach @ARGV' 〼 〇
〼 303030
〇 3c9b
O código-fonte dos dados do código do idioma (em squeeze Debian) está em /usr/share/i18n/locales/en_US
, que inclui /usr/share/i18n/locales/iso14651_t1_common
. Este arquivo não tem uma entrada para U3007
ou U303C
, nem estão incluídos em nenhum intervalo que eu possa encontrar.
Não estou familiarizado com as regras para criar a ordem de agrupamento , mas pelo que entendi, o fraseado relevante é
The symbol UNDEFINED shall be interpreted as including all coded character set values not specified explicitly or via the ellipsis symbol. (…) If no UNDEFINED symbol is specified, and the current coded character set contains characters not specified in this section, the utility shall issue a warning message and place such characters at the end of the character collation order.
Parece que o Glibc está ignorando caracteres que não estão especificados. Eu não sei se há uma falha no meu entendimento da especificação POSIX, se eu perdi alguma coisa na definição de código de idioma do Glibc, ou se há um bug no compilador de código de idioma do Glibc.