Abecední řazení v Linuxu (LC_COLLATE)

Martin Edlman edlman na fortech.cz
Pondělí Duben 26 09:52:28 CEST 2010


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Zdravím,

hledáním na Netu jsem nakonec našel řešení, na stejný problém se řazením
mezery si stěžují také Poláci, Španělé a další.

Snad se bude následující návod hodit i dalším. Následující popis funguje
na RH EL a Fedoře, jiný distro jsem nezkoušel.

Nejprve upravíme definice v textovým souboru
/usr/share/i18n/locales/cs_CZ, najdeme řádek <U0020>
IGNORE;IGNORE;IGNORE;<U0020>, který říká, že se má mezera v prvních
třech krocích ignorovat a ve čtvrtém použít. Tento řádek změníme na
<U0020> <U0020>;IGNORE;<U0020>;<U0020> (tuto definici jsem našel někde
na Inetu jako patch do pl_PL definic - problém s mezerou je nejen v
cs_CZ, ale téměř ve všech locale).

Potom je třeba vyhodit z archivu cs_CZ definice, překompilovat je a
znovu vložit do archivu.

# vypíšeme české definice, mělo by být cs_CZ, cs_CZ.utf8, cs_CZ.iso88592
localedef --list-archive | grep cs_CZ

# smažeme z archivu definice
localedef --delete-from-archive cs_CZ
localedef --delete-from-archive cs_CZ.utf8
localedef --delete-from-archive cs_CZ.iso88592

# vytvoříme novou binární podobu z textové definice
localedef -i /usr/share/i18n/locales/cs_CZ -f UTF-8 \
/usr/lib/locale/cs_CZ
localedef -i /usr/share/i18n/locales/cs_CZ -f UTF-8 \
/usr/lib/locale/cs_CZ.UTF-8
localedef -i /usr/share/i18n/locales/cs_CZ -f ISO-8859-2 \
/usr/lib/locale/cs_CZ.ISO-8859-2

# vytvoříme novou binární podobu z textové definice
localedef --add-to-archive cs_CZ
localedef --add-to-archive cs_CZ.UTF-8
localedef --add-to-archive cs_CZ.ISO-8859-2

# vypíšeme české definice, mělo by být cs_CZ, cs_CZ.utf8, cs_CZ.iso88592
localedef --list-archive | grep cs_CZ

No a teď by mělo být řazení v pořádku.


> narazil jsem v PostgreSQL na problém se řazením, jak jsem následně
> zjistil, není to problém PgSQL ale locale v systému (příkaz sort se
> chová stejně jako order by v PgSQL).
> 
> Chci seřadit Zdvořilý, Zdražil, ZD Písek
> Očekávám ZD Písek, Zdražil, Zdvořilý
> Dostanu Zdražil, ZD Písek, Zdvořilý
> 
> Tedy mezera v ZD Písek se ignoruje a řadí se jako ZDPísek.
> 
> Řazení je ovlivněno nastavením LC_COLLATE, popř. LANG. V definičním
> souboru /usr/share/i18n/locales/cs_CZ jsem našel poznámku
> 
> % Odlišnosti od normy:
> % ....
> % 3.2:
> % Mezera se řadí před první písmeno abecedy, ale každý znak mezery je
> % uvažován samostatně. Toto pravidlo je uplatněno na hesla, která jsou
> % si jinak rovna (v prvních třech průchodech).
> 
> Pokud tomu rozumím, tak se mezera uvažuje až při shodě, takže ZD Písek
> by se zařadil před ZDPísek (bez mezery shoda, mezera jde tedy dopředu).
> 
> Je možné změnit nějak jednoduše chování řazení? Lze něco změnit v
> uvedeném souboru a překompilovat ho? Zkoušel jsem měnit řádek
> 
> <U0020> IGNORE;IGNORE;IGNORE;<U0020>
> 
> který by měl definovat chování na mezeře, ale byly to spíš jen takové
> náhodné pokusy, syntaxi toho souboru moc nechápu.
> Taky nevím jestli pak tento soubor zkompilovat, zkoušel jsem příkaz
> 
> # localedef -i /usr/share/i18n/locales/cs_CZ  /usr/share/locale/cs_CZ/
> 
> ale sort se chová stále stejně, žádný náznak změny.
> 
> Můžete mi prosím poradit?

- -- 
S pozdravem,

Martin Edlman
Fortech, spol. s r.o,
Ropkova 51, 57001 Litomyšl
Public GPG key: http://edas.visaci.cz/#gpgkeys
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.10 (GNU/Linux)
Comment: Using GnuPG with Fedora - http://enigmail.mozdev.org/

iEYEARECAAYFAkvVRjwACgkQqmMakYm+VJ9FbACdF4HvPcDmPMV7/IujqTk6vDcJ
emEAoIkcdGd0Q8YoOORAO4KQXiBFIKad
=BoGu
-----END PGP SIGNATURE-----



Další informace o konferenci Linux